update .net core startup

pull/702/head
Luke Pulverenti 8 years ago
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("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);

@ -12,22 +12,18 @@ namespace Emby.Common.Implementations
/// <summary>
/// Initializes a new instance of the <see cref="BaseApplicationPaths"/> class.
/// </summary>
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; }
/// <summary>
/// Gets the path to the system folder
/// </summary>
public string ProgramSystemPath
{
get { return Path.GetDirectoryName(ApplicationPath); }
}
public string ProgramSystemPath { get; private set; }
/// <summary>
/// The _data directory

@ -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;
}
}
}

@ -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);

@ -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;
}

@ -14,6 +14,23 @@ namespace Emby.Common.Implementations.Net
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;
_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);
}
}
}

@ -23,10 +23,15 @@ namespace Emby.Common.Implementations.Net
/// </summary>
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;
}

@ -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;

@ -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);
}

@ -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;

@ -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)"
};

@ -12,8 +12,8 @@ namespace Emby.Server.Core
/// <summary>
/// Initializes a new instance of the <see cref="BaseApplicationPaths" /> class.
/// </summary>
public ServerApplicationPaths(string programDataPath, string applicationPath, string applicationResourcesPath)
: base(programDataPath, applicationPath)
public ServerApplicationPaths(string programDataPath, string appFolderPath, string applicationResourcesPath)
: base(programDataPath, appFolderPath)
{
ApplicationResourcesPath = applicationResourcesPath;
}

@ -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<ChannelItemResult> 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);

@ -396,6 +396,8 @@ namespace Emby.Server.Implementations.HttpServer
if (_disposed)
{
httpRes.StatusCode = 503;
httpRes.ContentType = "text/plain";
Write(httpRes, "Server shutting down");
return;
}

@ -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,25 +1700,15 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
.Replace("&quot;", "'");
writer.WriteElementString("plot", overview);
writer.WriteElementString("lockdata", true.ToString().ToLower());
if (timer.CommunityRating.HasValue)
if (lockData)
{
writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture));
writer.WriteElementString("lockdata", true.ToString().ToLower());
}
if (timer.IsSports)
{
AddGenre(timer.Genres, "Sports");
}
if (timer.IsKids)
{
AddGenre(timer.Genres, "Kids");
AddGenre(timer.Genres, "Children");
}
if (timer.IsNews)
if (timer.CommunityRating.HasValue)
{
AddGenre(timer.Genres, "News");
writer.WriteElementString("rating", timer.CommunityRating.Value.ToString(CultureInfo.InvariantCulture));
}
foreach (var genre in timer.Genres)
@ -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<XbmcMetadataOptions>("xbmcmetadata");
}
}
}

@ -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)
{

@ -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<TimerInfo> 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);
}
}

@ -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<IEnumerable<MediaSourceInfo>> 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<IEnumerable<MediaSourceInfo>> 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<BaseItemDto> 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<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);
@ -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<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);
@ -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<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));

@ -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<DynamicImageResponse> 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)
{

@ -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);
}

@ -6,12 +6,6 @@ namespace MediaBrowser.Common.Configuration
/// </summary>
public interface IApplicationPaths
{
/// <summary>
/// Gets the application path.
/// </summary>
/// <value>The application path.</value>
string ApplicationPath { get; }
/// <summary>
/// Gets the path to the program data folder
/// </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
/// </summary>
[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);
}
}
/// <summary>
/// Gets or sets the etag.
/// </summary>

@ -37,20 +37,22 @@ namespace MediaBrowser.MediaEncoding.Encoder
{
output = GetProcessOutput(encoderAppPath, "-version");
}
catch
catch (Exception ex)
{
if (logOutput)
{
_logger.ErrorException("Error validating encoder", ex);
}
}
output = output ?? string.Empty;
if (logOutput)
if (string.IsNullOrWhiteSpace(output))
{
_logger.Info("ffmpeg info: {0}", output);
return false;
}
if (string.IsNullOrWhiteSpace(output))
if (logOutput)
{
return false;
_logger.Info("ffmpeg info: {0}", output);
}
if (output.IndexOf("Libav developers", StringComparison.OrdinalIgnoreCase) != -1)

@ -308,6 +308,7 @@ namespace MediaBrowser.Model.IO
void SetReadOnly(string path, bool isHidden);
char DirectorySeparatorChar { get; }
char PathSeparator { get; }
string GetFullPath(string path);

@ -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

@ -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();
}

@ -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<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>();
@ -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);
}
}
}

@ -14,7 +14,11 @@ namespace Emby.Server.Core.Data
/// <summary>
/// Connects to db.
/// </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))
{

@ -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
/// <returns>ServerApplicationPaths.</returns>
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);
}
/// <summary>
@ -663,7 +667,7 @@ namespace MediaBrowser.ServerApplication
_logger.Info("Starting new instance");
//Application.Restart();
Process.Start(_appHost.ServerConfigurationManager.ApplicationPaths.ApplicationPath);
Process.Start(ApplicationPath);
ShutdownWindowsApplication();
}

@ -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);

@ -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()

@ -90,8 +90,6 @@ namespace MediaBrowser.XbmcMetadata.Savers
}
}
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
protected override List<string> GetTagsUsed()
{
var list = new List<string>

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
<version>3.0.689</version>
<version>3.0.691</version>
<title>Emby.Common</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
<version>3.0.689</version>
<version>3.0.691</version>
<title>Emby.Server.Core</title>
<authors>Emby Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Emby Server.</description>
<copyright>Copyright © Emby 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.689" />
<dependency id="MediaBrowser.Common" version="3.0.691" />
</dependencies>
</metadata>
<files>

@ -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);
}

@ -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()
{
}

@ -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);
}
/// <summary>
@ -139,34 +124,17 @@ namespace Emby.Server
}
}
if (!_isRunningAsService)
{
return false;
}
return false;
}
/// <summary>
/// Creates the application paths.
/// </summary>
/// <param name="applicationPath">The application path.</param>
/// <param name="runAsService">if set to <c>true</c> [run as service].</param>
/// <returns>ServerApplicationPaths.</returns>
private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, bool runAsService)
private static ServerApplicationPaths CreateApplicationPaths(string appDirectory)
{
var resourcesPath = Path.GetDirectoryName(applicationPath);
if (runAsService)
{
var systemPath = Path.GetDirectoryName(applicationPath);
var programDataPath = Path.GetDirectoryName(systemPath);
return new ServerApplicationPaths(programDataPath, applicationPath, resourcesPath);
}
var resourcesPath = appDirectory;
return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(applicationPath), applicationPath, resourcesPath);
return new ServerApplicationPaths(ApplicationPathHelper.GetProgramDataPath(appDirectory), appDirectory, resourcesPath);
}
/// <summary>
@ -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
/// </summary>
/// <param name="appPaths">The app paths.</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>
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<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 |
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<Task>(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);
}
/// <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>
/// Handles the UnhandledException event of the CurrentDomain control.
/// </summary>
@ -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
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
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;
}
/// <summary>
/// Sets the error mode.
/// </summary>

@ -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": {

Loading…
Cancel
Save