From 0e9cd51f9c64d4cfad5cb5c7b0ddae6af8d18ac6 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 13 Nov 2016 16:04:21 -0500 Subject: [PATCH] update .net core startup --- .../BaseApplicationHost.cs | 4 +- .../BaseApplicationPaths.cs | 10 +- .../EnvironmentInfo/EnvironmentInfo.cs | 10 + .../IO/ManagedFileSystem.cs | 8 + Emby.Common.Implementations/Net/NetSocket.cs | 9 + .../Net/SocketAcceptor.cs | 24 +- .../Net/SocketFactory.cs | 7 +- Emby.Server.Core/ApplicationHost.cs | 14 +- Emby.Server.Core/Data/DataExtensions.cs | 4 +- Emby.Server.Core/Data/SqliteItemRepository.cs | 19 +- .../SqliteNotificationsRepository.cs | 2 +- Emby.Server.Core/ServerApplicationPaths.cs | 4 +- .../Channels/ChannelManager.cs | 16 +- .../HttpServer/HttpListenerHost.cs | 2 + .../LiveTv/EmbyTV/EmbyTV.cs | 92 ++++++-- .../LiveTv/EmbyTV/ItemDataProvider.cs | 3 +- .../LiveTv/LiveTvDtoService.cs | 20 +- .../LiveTv/LiveTvManager.cs | 67 ++++-- .../LiveTv/ProgramImageProvider.cs | 14 +- MediaBrowser.Api/ApiEntryPoint.cs | 6 +- .../Configuration/IApplicationPaths.cs | 6 - MediaBrowser.Controller/Entities/BaseItem.cs | 19 +- .../Encoder/EncoderValidator.cs | 18 +- MediaBrowser.Model/IO/IFileSystem.cs | 1 + MediaBrowser.Model/System/IEnvironmentInfo.cs | 2 + MediaBrowser.Server.Mono/MonoAppHost.cs | 2 +- MediaBrowser.Server.Mono/Program.cs | 10 +- .../Persistence/SqliteExtensions.cs | 6 +- MediaBrowser.ServerApplication/MainStartup.cs | 28 ++- .../Updates/ApplicationUpdater.cs | 2 +- .../WindowsAppHost.cs | 9 +- .../Savers/SeriesNfoSaver.cs | 2 - Nuget/MediaBrowser.Common.nuspec | 2 +- Nuget/MediaBrowser.Server.Core.nuspec | 4 +- src/Emby.Server/ApplicationPathHelper.cs | 11 +- src/Emby.Server/CoreAppHost.cs | 2 +- src/Emby.Server/Program.cs | 213 +++--------------- src/Emby.Server/project.json | 8 +- 38 files changed, 355 insertions(+), 325 deletions(-) diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs index f0309511e0..1f194968c8 100644 --- a/Emby.Common.Implementations/BaseApplicationHost.cs +++ b/Emby.Common.Implementations/BaseApplicationHost.cs @@ -326,7 +326,7 @@ namespace Emby.Common.Implementations builder.AppendLine(string.Format("Processor count: {0}", Environment.ProcessorCount)); 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; } @@ -548,7 +548,7 @@ return null; TimerFactory = new TimerFactory(); RegisterSingleInstance(TimerFactory); - SocketFactory = new SocketFactory(null); + SocketFactory = new SocketFactory(LogManager.GetLogger("SocketFactory")); RegisterSingleInstance(SocketFactory); RegisterSingleInstance(CryptographyProvider); diff --git a/Emby.Common.Implementations/BaseApplicationPaths.cs b/Emby.Common.Implementations/BaseApplicationPaths.cs index 628d62bd48..8792778ba6 100644 --- a/Emby.Common.Implementations/BaseApplicationPaths.cs +++ b/Emby.Common.Implementations/BaseApplicationPaths.cs @@ -12,22 +12,18 @@ namespace Emby.Common.Implementations /// /// Initializes a new instance of the class. /// - protected BaseApplicationPaths(string programDataPath, string applicationPath) + protected BaseApplicationPaths(string programDataPath, string appFolderPath) { ProgramDataPath = programDataPath; - ApplicationPath = applicationPath; + ProgramSystemPath = appFolderPath; } - public string ApplicationPath { get; private set; } public string ProgramDataPath { get; private set; } /// /// Gets the path to the system folder /// - public string ProgramSystemPath - { - get { return Path.GetDirectoryName(ApplicationPath); } - } + public string ProgramSystemPath { get; private set; } /// /// The _data directory diff --git a/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs b/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs index 6a1b3ef74c..c040e39313 100644 --- a/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs +++ b/Emby.Common.Implementations/EnvironmentInfo/EnvironmentInfo.cs @@ -95,5 +95,15 @@ namespace Emby.Common.Implementations.EnvironmentInfo return MediaBrowser.Model.System.Architecture.X64; } } + + public string GetEnvironmentVariable(string name) + { + return Environment.GetEnvironmentVariable(name); + } + + public virtual string GetUserId() + { + return null; + } } } diff --git a/Emby.Common.Implementations/IO/ManagedFileSystem.cs b/Emby.Common.Implementations/IO/ManagedFileSystem.cs index 1f0aa55fac..83bb50f942 100644 --- a/Emby.Common.Implementations/IO/ManagedFileSystem.cs +++ b/Emby.Common.Implementations/IO/ManagedFileSystem.cs @@ -57,6 +57,14 @@ namespace Emby.Common.Implementations.IO } } + public char PathSeparator + { + get + { + return Path.DirectorySeparatorChar; + } + } + public string GetFullPath(string path) { return Path.GetFullPath(path); diff --git a/Emby.Common.Implementations/Net/NetSocket.cs b/Emby.Common.Implementations/Net/NetSocket.cs index faa1a81e2d..62ca3d6ac1 100644 --- a/Emby.Common.Implementations/Net/NetSocket.cs +++ b/Emby.Common.Implementations/Net/NetSocket.cs @@ -15,6 +15,15 @@ namespace Emby.Common.Implementations.Net public NetSocket(Socket socket, ILogger logger) { + if (socket == null) + { + throw new ArgumentNullException("socket"); + } + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + Socket = socket; _logger = logger; } diff --git a/Emby.Common.Implementations/Net/SocketAcceptor.cs b/Emby.Common.Implementations/Net/SocketAcceptor.cs index fd65e9fbc8..bddb7a079a 100644 --- a/Emby.Common.Implementations/Net/SocketAcceptor.cs +++ b/Emby.Common.Implementations/Net/SocketAcceptor.cs @@ -14,6 +14,23 @@ namespace Emby.Common.Implementations.Net public SocketAcceptor(ILogger logger, Socket originalSocket, Action onAccept, Func 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; _originalSocket = originalSocket; _isClosed = isClosed; @@ -101,11 +118,8 @@ namespace Emby.Common.Implementations.Net _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); } } } diff --git a/Emby.Common.Implementations/Net/SocketFactory.cs b/Emby.Common.Implementations/Net/SocketFactory.cs index 922b0f3cc5..f261376834 100644 --- a/Emby.Common.Implementations/Net/SocketFactory.cs +++ b/Emby.Common.Implementations/Net/SocketFactory.cs @@ -23,10 +23,15 @@ namespace Emby.Common.Implementations.Net /// private IPAddress _LocalIP; - private ILogger _logger; + private readonly ILogger _logger; public SocketFactory(ILogger logger) { + if (logger == null) + { + throw new ArgumentNullException("logger"); + } + _logger = logger; _LocalIP = IPAddress.Any; } diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs index 7f795a68de..d3d292ca58 100644 --- a/Emby.Server.Core/ApplicationHost.cs +++ b/Emby.Server.Core/ApplicationHost.cs @@ -725,6 +725,11 @@ namespace Emby.Server.Core try { + if (!FileSystemManager.FileExists(certificateLocation)) + { + return null; + } + X509Certificate2 localCert = new X509Certificate2(certificateLocation); //localCert.PrivateKey = PrivateKey.CreateFromFile(pvk_file).RSA; if (!localCert.HasPrivateKey) @@ -1438,12 +1443,7 @@ namespace Emby.Server.Core try { - AuthorizeServer( - UdpServerEntryPoint.PortNumber, - ServerConfigurationManager.Configuration.HttpServerPortNumber, - ServerConfigurationManager.Configuration.HttpsPortNumber, - ConfigurationManager.CommonApplicationPaths.ApplicationPath, - ConfigurationManager.CommonApplicationPaths.TempDirectory); + AuthorizeServer(); } 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(); public event EventHandler HasUpdateAvailableChanged; diff --git a/Emby.Server.Core/Data/DataExtensions.cs b/Emby.Server.Core/Data/DataExtensions.cs index b633d92178..631c1c5005 100644 --- a/Emby.Server.Core/Data/DataExtensions.cs +++ b/Emby.Server.Core/Data/DataExtensions.cs @@ -40,7 +40,7 @@ namespace Emby.Server.Core.Data public static IDataParameter Add(this IDataParameterCollection paramCollection, IDbCommand cmd, string name) { var param = cmd.CreateParameter(); - + param.ParameterName = name; paramCollection.Add(param); @@ -173,7 +173,7 @@ namespace Emby.Server.Core.Data var builder = new StringBuilder(); builder.AppendLine("alter table " + table); - builder.AppendLine("add column " + columnName + " " + type); + builder.AppendLine("add column " + columnName + " " + type + " NULL"); connection.RunQueries(new[] { builder.ToString() }, logger); } diff --git a/Emby.Server.Core/Data/SqliteItemRepository.cs b/Emby.Server.Core/Data/SqliteItemRepository.cs index 2ca86c8318..6ed409aa13 100644 --- a/Emby.Server.Core/Data/SqliteItemRepository.cs +++ b/Emby.Server.Core/Data/SqliteItemRepository.cs @@ -157,7 +157,7 @@ namespace Emby.Server.Core.Data 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 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", "Artists", "Text"); _connection.AddColumn(Logger, "TypedBaseItems", "AlbumArtists", "Text"); + _connection.AddColumn(Logger, "TypedBaseItems", "ExternalId", "Text"); _connection.AddColumn(Logger, "ItemValues", "CleanValue", "Text"); @@ -440,7 +441,8 @@ namespace Emby.Server.Core.Data "TotalBitrate", "ExtraType", "Artists", - "AlbumArtists" + "AlbumArtists", + "ExternalId" }; private readonly string[] _mediaStreamSaveColumns = @@ -575,7 +577,8 @@ namespace Emby.Server.Core.Data "TotalBitrate", "ExtraType", "Artists", - "AlbumArtists" + "AlbumArtists", + "ExternalId" }; _saveItemCommand = _connection.CreateCommand(); _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.ExecuteNonQuery(); @@ -1967,6 +1974,12 @@ namespace Emby.Server.Core.Data } index++; + if (!reader.IsDBNull(index)) + { + item.ExternalId = reader.GetString(index); + } + index++; + if (string.IsNullOrWhiteSpace(item.Tagline)) { var movie = item as Movie; diff --git a/Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs b/Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs index 8a7fc92701..dee0d4cfdd 100644 --- a/Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs +++ b/Emby.Server.Core/Notifications/SqliteNotificationsRepository.cs @@ -30,7 +30,7 @@ namespace Emby.Server.Core.Notifications { 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_Notifications2 on Notifications(UserId)" }; diff --git a/Emby.Server.Core/ServerApplicationPaths.cs b/Emby.Server.Core/ServerApplicationPaths.cs index d59dd89d9c..dc80b773c5 100644 --- a/Emby.Server.Core/ServerApplicationPaths.cs +++ b/Emby.Server.Core/ServerApplicationPaths.cs @@ -12,8 +12,8 @@ namespace Emby.Server.Core /// /// Initializes a new instance of the class. /// - public ServerApplicationPaths(string programDataPath, string applicationPath, string applicationResourcesPath) - : base(programDataPath, applicationPath) + public ServerApplicationPaths(string programDataPath, string appFolderPath, string applicationResourcesPath) + : base(programDataPath, appFolderPath) { ApplicationResourcesPath = applicationResourcesPath; } diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 2ce880c93a..94ff7c3426 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -326,7 +326,7 @@ namespace Emby.Server.Implementations.Channels if (requiresCallback != null) { - results = await GetChannelItemMediaSourcesInternal(requiresCallback, item.ExternalId, cancellationToken) + results = await GetChannelItemMediaSourcesInternal(requiresCallback, GetItemExternalId(item), cancellationToken) .ConfigureAwait(false); } else @@ -1075,6 +1075,18 @@ namespace Emby.Server.Implementations.Channels 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 async Task GetChannelItems(IChannel channel, User user, @@ -1145,7 +1157,7 @@ namespace Emby.Server.Implementations.Channels { var categoryItem = _libraryManager.GetItemById(new Guid(folderId)); - query.FolderId = categoryItem.ExternalId; + query.FolderId = GetItemExternalId(categoryItem); } var result = await channel.GetChannelItems(query, cancellationToken).ConfigureAwait(false); diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 41b7a4622e..876d140ecb 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -396,6 +396,8 @@ namespace Emby.Server.Implementations.HttpServer if (_disposed) { httpRes.StatusCode = 503; + httpRes.ContentType = "text/plain"; + Write(httpRes, "Server shutting down"); return; } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 63356a8451..aaf74b5c68 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1551,13 +1551,28 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { 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) { SaveSeriesNfo(timer, recordingPath, seriesPath); + SaveVideoNfo(timer, recordingPath, false); } else if (!timer.IsMovie || timer.IsSports || timer.IsNews) { - SaveVideoNfo(timer, recordingPath); + SaveVideoNfo(timer, recordingPath, true); } } catch (Exception ex) @@ -1594,6 +1609,16 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV 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.WriteEndDocument(); } @@ -1601,7 +1626,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV } 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"); @@ -1622,11 +1647,41 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV using (XmlWriter writer = XmlWriter.Create(stream, settings)) { 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)); @@ -1645,27 +1700,17 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV .Replace(""", "'"); writer.WriteElementString("plot", overview); - writer.WriteElementString("lockdata", true.ToString().ToLower()); + + if (lockData) + { + writer.WriteElementString("lockdata", true.ToString().ToLower()); + } if (timer.CommunityRating.HasValue) { 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) { writer.WriteElementString("genre", genre); @@ -1968,4 +2013,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV public CancellationTokenSource CancellationTokenSource { get; set; } } } + public static class ConfigurationExtension + { + public static XbmcMetadataOptions GetNfoConfiguration(this IConfigurationManager manager) + { + return manager.GetConfiguration("xbmcmetadata"); + } + } } \ No newline at end of file diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs index ded4f04c4a..16ae26d45d 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/ItemDataProvider.cs @@ -54,9 +54,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV catch (FileNotFoundException) { } - catch (IOException ex) + catch (IOException) { - Logger.ErrorException("Error deserializing {0}", ex, jsonFile); } catch (Exception ex) { diff --git a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs index 4e71615210..d3e30a46b2 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -269,6 +269,18 @@ namespace Emby.Server.Implementations.LiveTv 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 GetTimerInfo(TimerInfoDto dto, bool isNew, LiveTvManager liveTv, CancellationToken cancellationToken) { var info = new TimerInfo @@ -304,7 +316,7 @@ namespace Emby.Server.Implementations.LiveTv if (channel != null) { - info.ChannelId = channel.ExternalId; + info.ChannelId = GetItemExternalId(channel); } } @@ -314,7 +326,7 @@ namespace Emby.Server.Implementations.LiveTv if (program != null) { - info.ProgramId = program.ExternalId; + info.ProgramId = GetItemExternalId(program); } } @@ -370,7 +382,7 @@ namespace Emby.Server.Implementations.LiveTv if (channel != null) { - info.ChannelId = channel.ExternalId; + info.ChannelId = GetItemExternalId(channel); } } @@ -380,7 +392,7 @@ namespace Emby.Server.Implementations.LiveTv if (program != null) { - info.ProgramId = program.ExternalId; + info.ProgramId = GetItemExternalId(program); } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index adec668589..3a6f23fe95 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -251,12 +251,24 @@ namespace Emby.Server.Implementations.LiveTv 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> GetRecordingMediaSources(IHasMediaSources item, CancellationToken cancellationToken) { var baseItem = (BaseItem)item; 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> GetChannelMediaSources(IHasMediaSources item, CancellationToken cancellationToken) @@ -313,18 +325,18 @@ namespace Emby.Server.Implementations.LiveTv var channel = GetInternalChannel(id); isVideo = channel.ChannelType == ChannelType.TV; 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; 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; directStreamProvider = streamInfo.Item2; } else { - info = await service.GetChannelStream(channel.ExternalId, mediaSourceId, cancellationToken).ConfigureAwait(false); + info = await service.GetChannelStream(GetItemExternalId(channel), mediaSourceId, cancellationToken).ConfigureAwait(false); } info.RequiresClosing = true; @@ -341,8 +353,8 @@ namespace Emby.Server.Implementations.LiveTv isVideo = !string.Equals(recording.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase); service = GetService(recording); - _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, recording.ExternalId); - info = await service.GetRecordingStream(recording.ExternalId, null, cancellationToken).ConfigureAwait(false); + _logger.Info("Opening recording stream from {0}, external recording Id: {1}", service.Name, GetItemExternalId(recording)); + info = await service.GetRecordingStream(GetItemExternalId(recording), null, cancellationToken).ConfigureAwait(false); info.RequiresClosing = true; if (info.RequiresClosing) @@ -493,7 +505,7 @@ namespace Emby.Server.Implementations.LiveTv isNew = true; } - if (!string.Equals(channelInfo.Id, item.ExternalId)) + if (!string.Equals(channelInfo.Id, item.ExternalId, StringComparison.Ordinal)) { isNew = true; } @@ -601,7 +613,6 @@ namespace Emby.Server.Implementations.LiveTv item.EpisodeTitle = info.EpisodeTitle; item.ExternalId = info.Id; - item.ExternalSeriesIdLegacy = seriesId; if (!string.IsNullOrWhiteSpace(seriesId) && !string.Equals(item.ExternalSeriesId, seriesId, StringComparison.Ordinal)) { @@ -841,6 +852,13 @@ namespace Emby.Server.Implementations.LiveTv return item.Id; } + + + private string GetExternalSeriesIdLegacy(BaseItem item) + { + return item.GetProviderId("ProviderExternalSeriesId"); + } + public async Task GetProgram(string id, CancellationToken cancellationToken, User user = null) { var program = GetInternalProgram(id); @@ -848,7 +866,15 @@ namespace Emby.Server.Implementations.LiveTv var dto = _dtoService.GetBaseItemDto(program, new DtoOptions(), user); var list = new List>(); - list.Add(new Tuple(dto, program.ServiceName, program.ExternalId, program.ExternalSeriesIdLegacy)); + + var externalSeriesId = program.ExternalSeriesId; + + if (string.IsNullOrWhiteSpace(externalSeriesId)) + { + externalSeriesId = GetExternalSeriesIdLegacy(program); + } + + list.Add(new Tuple(dto, program.ServiceName, GetItemExternalId(program), externalSeriesId)); await AddRecordingInfo(list, cancellationToken).ConfigureAwait(false); @@ -1283,7 +1309,7 @@ namespace Emby.Server.Implementations.LiveTv var isKids = 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 { @@ -1830,7 +1856,14 @@ namespace Emby.Server.Implementations.LiveTv dto.ServiceName = serviceName; } - programTuples.Add(new Tuple(dto, serviceName, program.ExternalId, program.ExternalSeriesIdLegacy)); + var externalSeriesId = program.ExternalSeriesId; + + if (string.IsNullOrWhiteSpace(externalSeriesId)) + { + externalSeriesId = GetExternalSeriesIdLegacy(program); + } + + programTuples.Add(new Tuple(dto, serviceName, GetItemExternalId(program), externalSeriesId)); } await AddRecordingInfo(programTuples, CancellationToken.None).ConfigureAwait(false); @@ -2006,7 +2039,7 @@ namespace Emby.Server.Implementations.LiveTv 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 - return service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None); + return service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None); } return Task.FromResult(true); @@ -2030,7 +2063,7 @@ namespace Emby.Server.Implementations.LiveTv try { - await service.DeleteRecordingAsync(recording.ExternalId, CancellationToken.None).ConfigureAwait(false); + await service.DeleteRecordingAsync(GetItemExternalId(recording), CancellationToken.None).ConfigureAwait(false); } catch (ResourceNotFoundException) { @@ -2289,12 +2322,12 @@ namespace Emby.Server.Implementations.LiveTv programInfo = new ProgramInfo { Audio = program.Audio, - ChannelId = channel.ExternalId, + ChannelId = GetItemExternalId(channel), CommunityRating = program.CommunityRating, EndDate = program.EndDate ?? DateTime.MinValue, EpisodeTitle = program.EpisodeTitle, Genres = program.Genres, - Id = program.ExternalId, + Id = GetItemExternalId(program), IsHD = program.IsHD, IsKids = program.IsKids, IsLive = program.IsLive, @@ -2360,7 +2393,7 @@ namespace Emby.Server.Implementations.LiveTv info.Name = program.Name; info.Overview = program.Overview; info.ProgramId = programDto.Id; - info.ExternalProgramId = program.ExternalId; + info.ExternalProgramId = GetItemExternalId(program); if (program.EndDate.HasValue) { @@ -2804,7 +2837,7 @@ namespace Emby.Server.Implementations.LiveTv public async Task SaveListingProvider(ListingsProviderInfo info, bool validateLogin, bool validateListings) { - info = _jsonSerializer.DeserializeFromString< ListingsProviderInfo>(_jsonSerializer.SerializeToString(info)); + info = _jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(info)); var provider = _listingProviders.FirstOrDefault(i => string.Equals(info.Type, i.Type, StringComparison.OrdinalIgnoreCase)); diff --git a/Emby.Server.Implementations/LiveTv/ProgramImageProvider.cs b/Emby.Server.Implementations/LiveTv/ProgramImageProvider.cs index f5d298af4c..5a0389b16a 100644 --- a/Emby.Server.Implementations/LiveTv/ProgramImageProvider.cs +++ b/Emby.Server.Implementations/LiveTv/ProgramImageProvider.cs @@ -24,6 +24,18 @@ namespace Emby.Server.Implementations.LiveTv 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 GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken) { var liveTvItem = (LiveTvProgram)item; @@ -38,7 +50,7 @@ namespace Emby.Server.Implementations.LiveTv { 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) { diff --git a/MediaBrowser.Api/ApiEntryPoint.cs b/MediaBrowser.Api/ApiEntryPoint.cs index bc02417669..37ab123667 100644 --- a/MediaBrowser.Api/ApiEntryPoint.cs +++ b/MediaBrowser.Api/ApiEntryPoint.cs @@ -128,7 +128,11 @@ namespace MediaBrowser.Api { // 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); } diff --git a/MediaBrowser.Common/Configuration/IApplicationPaths.cs b/MediaBrowser.Common/Configuration/IApplicationPaths.cs index d3bf033029..d2446ce46d 100644 --- a/MediaBrowser.Common/Configuration/IApplicationPaths.cs +++ b/MediaBrowser.Common/Configuration/IApplicationPaths.cs @@ -6,12 +6,6 @@ namespace MediaBrowser.Common.Configuration /// public interface IApplicationPaths { - /// - /// Gets the application path. - /// - /// The application path. - string ApplicationPath { get; } - /// /// Gets the path to the program data folder /// diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index b079da97ce..10cac79922 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -296,28 +296,11 @@ namespace MediaBrowser.Controller.Entities /// If this content came from an external service, the id of the content on that service /// [IgnoreDataMember] - public string ExternalId - { - get { return this.GetProviderId("ProviderExternalId"); } - set - { - this.SetProviderId("ProviderExternalId", value); - } - } + public string ExternalId { get; set; } [IgnoreDataMember] public string ExternalSeriesId { get; set; } - [IgnoreDataMember] - public string ExternalSeriesIdLegacy - { - get { return this.GetProviderId("ProviderExternalSeriesId"); } - set - { - this.SetProviderId("ProviderExternalSeriesId", value); - } - } - /// /// Gets or sets the etag. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 6acdccf3df..1b8b3feec6 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -37,15 +37,12 @@ namespace MediaBrowser.MediaEncoding.Encoder { output = GetProcessOutput(encoderAppPath, "-version"); } - catch + catch (Exception ex) { - } - - output = output ?? string.Empty; - - if (logOutput) - { - _logger.Info("ffmpeg info: {0}", output); + if (logOutput) + { + _logger.ErrorException("Error validating encoder", ex); + } } if (string.IsNullOrWhiteSpace(output)) @@ -53,6 +50,11 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } + if (logOutput) + { + _logger.Info("ffmpeg info: {0}", output); + } + if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1) { return false; diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index f219d92959..22e1e77586 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -308,6 +308,7 @@ namespace MediaBrowser.Model.IO void SetReadOnly(string path, bool isHidden); char DirectorySeparatorChar { get; } + char PathSeparator { get; } string GetFullPath(string path); diff --git a/MediaBrowser.Model/System/IEnvironmentInfo.cs b/MediaBrowser.Model/System/IEnvironmentInfo.cs index c5f493e7c9..7e7d81e30b 100644 --- a/MediaBrowser.Model/System/IEnvironmentInfo.cs +++ b/MediaBrowser.Model/System/IEnvironmentInfo.cs @@ -12,6 +12,8 @@ namespace MediaBrowser.Model.System string OperatingSystemName { get; } string OperatingSystemVersion { get; } Architecture SystemArchitecture { get; } + string GetEnvironmentVariable(string name); + string GetUserId(); } public enum OperatingSystem diff --git a/MediaBrowser.Server.Mono/MonoAppHost.cs b/MediaBrowser.Server.Mono/MonoAppHost.cs index 5f0ecde24e..fd3c9f506d 100644 --- a/MediaBrowser.Server.Mono/MonoAppHost.cs +++ b/MediaBrowser.Server.Mono/MonoAppHost.cs @@ -91,7 +91,7 @@ namespace MediaBrowser.Server.Mono MainClass.Shutdown(); } - protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory) + protected override void AuthorizeServer() { throw new NotImplementedException(); } diff --git a/MediaBrowser.Server.Mono/Program.cs b/MediaBrowser.Server.Mono/Program.cs index 48390f0784..470525eced 100644 --- a/MediaBrowser.Server.Mono/Program.cs +++ b/MediaBrowser.Server.Mono/Program.cs @@ -5,6 +5,7 @@ using MediaBrowser.Server.Startup.Common; using Microsoft.Win32; using System; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Linq; using System.Net; @@ -74,7 +75,9 @@ namespace MediaBrowser.Server.Mono 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 ApplicationTaskCompletionSource = new TaskCompletionSource(); @@ -305,5 +308,10 @@ namespace MediaBrowser.Server.Mono public class MonoEnvironmentInfo : EnvironmentInfo { public bool IsBsd { get; set; } + + public virtual string GetUserId() + { + return Syscall.getuid().ToString(CultureInfo.InvariantCulture); + } } } diff --git a/MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs b/MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs index 72ecfc1bf5..22aeb53dd7 100644 --- a/MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs +++ b/MediaBrowser.Server.Startup.Common/Persistence/SqliteExtensions.cs @@ -14,7 +14,11 @@ namespace Emby.Server.Core.Data /// /// Connects to db. /// - public static async Task ConnectToDb(string dbPath, bool isReadOnly, bool enablePooling, int? cacheSize, ILogger logger) + public static async Task ConnectToDb(string dbPath, + bool isReadOnly, + bool enablePooling, + int? cacheSize, + ILogger logger) { if (string.IsNullOrEmpty(dbPath)) { diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs index ab0a36affb..c0ebcde74a 100644 --- a/MediaBrowser.ServerApplication/MainStartup.cs +++ b/MediaBrowser.ServerApplication/MainStartup.cs @@ -44,6 +44,8 @@ namespace MediaBrowser.ServerApplication [DllImport("kernel32.dll", SetLastError = true)] static extern bool SetDllDirectory(string lpPathName); + public static string ApplicationPath; + public static bool TryGetLocalFromUncDirectory(string local, out string unc) { if ((local == null) || (local == "")) @@ -81,14 +83,14 @@ namespace MediaBrowser.ServerApplication var currentProcess = Process.GetCurrentProcess(); - var applicationPath = currentProcess.MainModule.FileName; - var architecturePath = Path.Combine(Path.GetDirectoryName(applicationPath), Environment.Is64BitProcess ? "x64" : "x86"); + ApplicationPath = currentProcess.MainModule.FileName; + var architecturePath = Path.Combine(Path.GetDirectoryName(ApplicationPath), Environment.Is64BitProcess ? "x64" : "x86"); Wand.SetMagickCoderModulePath(architecturePath); var success = SetDllDirectory(architecturePath); - var appPaths = CreateApplicationPaths(applicationPath, IsRunningAsService); + var appPaths = CreateApplicationPaths(ApplicationPath, IsRunningAsService); var logManager = new NlogManager(appPaths.LogDirectoryPath, "server"); logManager.ReloadLogger(LogSeverity.Debug); @@ -102,7 +104,7 @@ namespace MediaBrowser.ServerApplication if (options.ContainsOption("-installservice")) { logger.Info("Performing service installation"); - InstallService(applicationPath, logger); + InstallService(ApplicationPath, logger); return; } @@ -110,7 +112,7 @@ namespace MediaBrowser.ServerApplication if (options.ContainsOption("-installserviceasadmin")) { logger.Info("Performing service installation"); - RunServiceInstallation(applicationPath); + RunServiceInstallation(ApplicationPath); return; } @@ -118,7 +120,7 @@ namespace MediaBrowser.ServerApplication if (options.ContainsOption("-uninstallservice")) { logger.Info("Performing service uninstallation"); - UninstallService(applicationPath, logger); + UninstallService(ApplicationPath, logger); return; } @@ -126,15 +128,15 @@ namespace MediaBrowser.ServerApplication if (options.ContainsOption("-uninstallserviceasadmin")) { logger.Info("Performing service uninstallation"); - RunServiceUninstallation(applicationPath); + RunServiceUninstallation(ApplicationPath); return; } 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."); return; @@ -250,6 +252,8 @@ namespace MediaBrowser.ServerApplication /// ServerApplicationPaths. private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService) { + var appFolderPath = Path.GetDirectoryName(applicationPath); + var resourcesPath = Path.GetDirectoryName(applicationPath); if (runAsService) @@ -258,10 +262,10 @@ namespace MediaBrowser.ServerApplication 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); } /// @@ -663,7 +667,7 @@ namespace MediaBrowser.ServerApplication _logger.Info("Starting new instance"); //Application.Restart(); - Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath); + Process.Start(ApplicationPath); ShutdownWindowsApplication(); } diff --git a/MediaBrowser.ServerApplication/Updates/ApplicationUpdater.cs b/MediaBrowser.ServerApplication/Updates/ApplicationUpdater.cs index c426395b76..97537b27d0 100644 --- a/MediaBrowser.ServerApplication/Updates/ApplicationUpdater.cs +++ b/MediaBrowser.ServerApplication/Updates/ApplicationUpdater.cs @@ -44,7 +44,7 @@ namespace MediaBrowser.ServerApplication.Updates // startpath = executable to launch // 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}\"", - 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); Process.Start(tempUpdater, args); diff --git a/MediaBrowser.ServerApplication/WindowsAppHost.cs b/MediaBrowser.ServerApplication/WindowsAppHost.cs index 8fd7184321..d9bead6b7c 100644 --- a/MediaBrowser.ServerApplication/WindowsAppHost.cs +++ b/MediaBrowser.ServerApplication/WindowsAppHost.cs @@ -6,6 +6,7 @@ using System.Reflection; using Emby.Server.Core; using Emby.Server.Core.Data; using Emby.Server.Core.FFMpeg; +using Emby.Server.Implementations.EntryPoints; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.System; @@ -60,9 +61,13 @@ namespace MediaBrowser.ServerApplication 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() diff --git a/MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs index 4c22f0246f..b512939a7f 100644 --- a/MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs +++ b/MediaBrowser.XbmcMetadata/Savers/SeriesNfoSaver.cs @@ -90,8 +90,6 @@ namespace MediaBrowser.XbmcMetadata.Savers } } - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - protected override List GetTagsUsed() { var list = new List diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 464a29eb23..daeb754bac 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Common - 3.0.689 + 3.0.691 Emby.Common Emby Team ebr,Luke,scottisafool diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 96e9a697a2..a34a9bee20 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ MediaBrowser.Server.Core - 3.0.689 + 3.0.691 Emby.Server.Core Emby Team ebr,Luke,scottisafool @@ -12,7 +12,7 @@ Contains core components required to build plugins for Emby Server. Copyright © Emby 2013 - + diff --git a/src/Emby.Server/ApplicationPathHelper.cs b/src/Emby.Server/ApplicationPathHelper.cs index 4da87b6a06..c611ff3727 100644 --- a/src/Emby.Server/ApplicationPathHelper.cs +++ b/src/Emby.Server/ApplicationPathHelper.cs @@ -8,7 +8,7 @@ namespace Emby.Server { public class ApplicationPathHelper { - public static string GetProgramDataPath(string applicationPath) + public static string GetProgramDataPath(string appDirectory) { var useDebugPath = false; @@ -27,14 +27,7 @@ namespace Emby.Server // If it's a relative path, e.g. "..\" if (!Path.IsPathRooted(programDataPath)) { - var path = Path.GetDirectoryName(applicationPath); - - if (string.IsNullOrEmpty(path)) - { - throw new Exception("Unable to determine running assembly location"); - } - - programDataPath = Path.Combine(path, programDataPath); + programDataPath = Path.Combine(appDirectory, programDataPath); programDataPath = Path.GetFullPath(programDataPath); } diff --git a/src/Emby.Server/CoreAppHost.cs b/src/Emby.Server/CoreAppHost.cs index 1a15265130..21f6ae4456 100644 --- a/src/Emby.Server/CoreAppHost.cs +++ b/src/Emby.Server/CoreAppHost.cs @@ -51,7 +51,7 @@ namespace Emby.Server return list; } - protected override void AuthorizeServer(int udpPort, int httpServerPort, int httpsServerPort, string applicationPath, string tempDirectory) + protected override void AuthorizeServer() { } diff --git a/src/Emby.Server/Program.cs b/src/Emby.Server/Program.cs index 64fc423a16..6f871990d1 100644 --- a/src/Emby.Server/Program.cs +++ b/src/Emby.Server/Program.cs @@ -28,8 +28,6 @@ namespace Emby.Server private static ILogger _logger; - private static bool _isRunningAsService = false; - private static bool _canRestartService = false; private static bool _appHostDisposed; [DllImport("kernel32.dll", SetLastError = true)] @@ -41,39 +39,33 @@ namespace Emby.Server public static void Main(string[] args) { var options = new StartupOptions(); - _isRunningAsService = options.ContainsOption("-service"); - - if (_isRunningAsService) - { - //_canRestartService = CanRestartWindowsService(); - } 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"); //Wand.SetMagickCoderModulePath(architecturePath); //var success = SetDllDirectory(architecturePath); - var appPaths = CreateApplicationPaths(applicationPath, _isRunningAsService); + var appPaths = CreateApplicationPaths(baseDirectory); var logManager = new NlogManager(appPaths.LogDirectoryPath, "server"); logManager.ReloadLogger(LogSeverity.Debug); logManager.AddConsoleOutput(); var logger = _logger = logManager.GetLogger("Main"); - + ApplicationHost.LogEnvironmentInfo(logger, appPaths, true); AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - if (IsAlreadyRunning(applicationPath, currentProcess)) - { - logger.Info("Shutting down because another instance of Emby Server is already running."); - return; - } + //if (IsAlreadyRunning(applicationPath, currentProcess)) + //{ + // logger.Info("Shutting down because another instance of Emby Server is already running."); + // return; + //} if (PerformUpdateIfNeeded(appPaths, logger)) { @@ -81,14 +73,7 @@ namespace Emby.Server return; } - try - { - RunApplication(appPaths, logManager, _isRunningAsService, options); - } - finally - { - OnServiceShutdown(); - } + RunApplication(appPaths, logManager, options); } /// @@ -139,34 +124,17 @@ namespace Emby.Server } } - if (!_isRunningAsService) - { - return false; - } - return false; } /// /// Creates the application paths. /// - /// The application path. - /// if set to true [run as service]. - /// ServerApplicationPaths. - private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService) + private static ServerApplicationPaths CreateApplicationPaths(string appDirectory) { - var resourcesPath = Path.GetDirectoryName(applicationPath); + var resourcesPath = appDirectory; - if (runAsService) - { - var systemPath = Path.GetDirectoryName(applicationPath); - - var programDataPath = Path.GetDirectoryName(systemPath); - - return new ServerApplicationPaths(programDataPath, applicationPath, resourcesPath); - } - - return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), applicationPath, resourcesPath); + return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(appDirectory), appDirectory, resourcesPath); } /// @@ -177,14 +145,7 @@ namespace Emby.Server { get { - if (_isRunningAsService) - { - return _canRestartService; - } - else - { - return true; - } + return true; } } @@ -196,14 +157,7 @@ namespace Emby.Server { get { - if (_isRunningAsService) - { - return _canRestartService; - } - else - { - return true; - } + return false; } } @@ -214,9 +168,8 @@ namespace Emby.Server /// /// The app paths. /// The log manager. - /// if set to true [run service]. /// The options. - 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); @@ -240,29 +193,19 @@ namespace Emby.Server var initProgress = new Progress(); - 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 | - ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX); - } + // Not crazy about this but it's the only way to suppress ffmpeg crash dialog boxes + SetErrorMode(ErrorModes.SEM_FAILCRITICALERRORS | ErrorModes.SEM_NOALIGNMENTFAULTEXCEPT | + ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX); var task = _appHost.Init(initProgress); Task.WaitAll(task); task = task.ContinueWith(new Action(a => _appHost.RunStartupTasks()), TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent); - if (runService) - { - StartService(logManager); - } - else - { - Task.WaitAll(task); + Task.WaitAll(task); - task = ApplicationTaskCompletionSource.Task; - Task.WaitAll(task); - } + task = ApplicationTaskCompletionSource.Task; + Task.WaitAll(task); } private static void GenerateCertificate(string certPath, string certHost) @@ -270,31 +213,6 @@ namespace Emby.Server //CertificateGenerator.CreateSelfSignCertificatePfx(certPath, certHost, _logger); } - /// - /// Starts the service. - /// - private static void StartService(ILogManager logManager) - { - } - - /// - /// Handles the Disposed event of the service control. - /// - /// The source of the event. - /// The instance containing the event data. - static void service_Disposed(object sender, EventArgs e) - { - ApplicationTaskCompletionSource.SetResult(true); - OnServiceShutdown(); - } - - private static void OnServiceShutdown() - { - _logger.Info("Shutting down"); - - DisposeAppHost(); - } - /// /// Handles the UnhandledException event of the CurrentDomain control. /// @@ -306,10 +224,7 @@ namespace Emby.Server 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) { @@ -325,29 +240,6 @@ namespace Emby.Server /// true if XXXX, false otherwise 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; } @@ -358,37 +250,25 @@ namespace Emby.Server public static void Shutdown() { - if (_isRunningAsService) - { - ShutdownWindowsService(); - } - else - { - DisposeAppHost(); + 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() { DisposeAppHost(); - if (_isRunningAsService) - { - RestartWindowsService(); - } - else - { - //_logger.Info("Hiding server notify icon"); - //_serverNotifyIcon.Visible = false; + // todo: start new instance - _logger.Info("Starting new instance"); - //Application.Restart(); - Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath); - - ShutdownWindowsApplication(); - } + Shutdown(); } 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; - } - /// /// Sets the error mode. /// diff --git a/src/Emby.Server/project.json b/src/Emby.Server/project.json index c64db844f9..55acee5146 100644 --- a/src/Emby.Server/project.json +++ b/src/Emby.Server/project.json @@ -12,10 +12,10 @@ "version": "1.0.1" }, "Mono.Nat": "1.0.0-*", - "Microsoft.Win32.Registry": "4.0.0", - "System.Runtime.Extensions": "4.1.0", - "System.Diagnostics.Process": "4.1.0", - "Microsoft.Data.SQLite": "1.0.0" + "Microsoft.Win32.Registry": "4.0.0", + "System.Runtime.Extensions": "4.1.0", + "System.Diagnostics.Process": "4.1.0", + "Microsoft.Data.SQLite": "1.1.0-preview1-final" }, "frameworks": {