From 976459d3e8a8b889cebc2cf281e38b0fbc19c9b9 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Tue, 17 Dec 2019 23:15:02 +0100 Subject: [PATCH 001/517] Rewrite WebSocket handling code --- Emby.Dlna/PlayTo/PlayToController.cs | 6 +- Emby.Dlna/PlayTo/PlayToManager.cs | 2 +- .../ApplicationHost.cs | 34 +-- .../HttpServer/HttpListenerHost.cs | 160 +++++++------ .../HttpServer/IHttpListener.cs | 40 ---- .../HttpServer/WebSocketConnection.cs | 215 +++++++++--------- Emby.Server.Implementations/Net/IWebSocket.cs | 48 ---- .../Net/WebSocketConnectEventArgs.cs | 31 --- .../Session/HttpSessionController.cs | 191 ---------------- .../Session/SessionManager.cs | 13 +- .../Session/SessionWebSocketListener.cs | 36 +-- .../Session/WebSocketController.cs | 70 +++--- .../SocketSharp/SharpWebSocket.cs | 105 --------- .../SocketSharp/WebSocketSharpListener.cs | 138 ----------- Jellyfin.Server/Startup.cs | 2 - .../Session/SessionInfoWebSocketListener.cs | 43 ++-- .../IServerApplicationHost.cs | 2 - .../Net/BasePeriodicWebSocketListener.cs | 1 - MediaBrowser.Controller/Net/IHttpServer.cs | 22 +- .../Net/IWebSocketConnection.cs | 28 +-- .../Session/ISessionController.cs | 3 +- .../Session/SessionInfo.cs | 80 ++----- MediaBrowser.Model/Net/WebSocketMessage.cs | 8 +- 23 files changed, 316 insertions(+), 962 deletions(-) delete mode 100644 Emby.Server.Implementations/HttpServer/IHttpListener.cs delete mode 100644 Emby.Server.Implementations/Net/IWebSocket.cs delete mode 100644 Emby.Server.Implementations/Net/WebSocketConnectEventArgs.cs delete mode 100644 Emby.Server.Implementations/Session/HttpSessionController.cs delete mode 100644 Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs delete mode 100644 Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index c58f16438b..a215c9f4bf 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -6,7 +6,6 @@ using System.Threading; using System.Threading.Tasks; using Emby.Dlna.Didl; using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; @@ -899,7 +898,8 @@ namespace Emby.Dlna.PlayTo return 0; } - public Task SendMessage(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken) + /// + public Task SendMessage(string name, Guid messageId, T data, CancellationToken cancellationToken) { if (_disposed) { @@ -915,10 +915,12 @@ namespace Emby.Dlna.PlayTo { return SendPlayCommand(data as PlayRequest, cancellationToken); } + if (string.Equals(name, "PlayState", StringComparison.OrdinalIgnoreCase)) { return SendPlaystateCommand(data as PlaystateRequest, cancellationToken); } + if (string.Equals(name, "GeneralCommand", StringComparison.OrdinalIgnoreCase)) { return SendGeneralCommand(data as GeneralCommand, cancellationToken); diff --git a/Emby.Dlna/PlayTo/PlayToManager.cs b/Emby.Dlna/PlayTo/PlayToManager.cs index 2ca44b7ea2..943d52b0d7 100644 --- a/Emby.Dlna/PlayTo/PlayToManager.cs +++ b/Emby.Dlna/PlayTo/PlayToManager.cs @@ -21,7 +21,7 @@ using Microsoft.Extensions.Logging; namespace Emby.Dlna.PlayTo { - class PlayToManager : IDisposable + public class PlayToManager : IDisposable { private readonly ILogger _logger; private readonly ISessionManager _sessionManager; diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 0bb1d832fb..e3e071af95 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -45,7 +45,6 @@ using Emby.Server.Implementations.ScheduledTasks; using Emby.Server.Implementations.Security; using Emby.Server.Implementations.Serialization; using Emby.Server.Implementations.Session; -using Emby.Server.Implementations.SocketSharp; using Emby.Server.Implementations.TV; using Emby.Server.Implementations.Updates; using MediaBrowser.Api; @@ -105,7 +104,6 @@ using MediaBrowser.Providers.TV.TheTVDB; using MediaBrowser.WebDashboard.Api; using MediaBrowser.XbmcMetadata.Providers; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -629,32 +627,8 @@ namespace Emby.Server.Implementations } } - public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func next) - { - if (!context.WebSockets.IsWebSocketRequest) - { - await next().ConfigureAwait(false); - return; - } - - await HttpServer.ProcessWebSocketRequest(context).ConfigureAwait(false); - } - - public async Task ExecuteHttpHandlerAsync(HttpContext context, Func next) - { - if (context.WebSockets.IsWebSocketRequest) - { - await next().ConfigureAwait(false); - return; - } - - var request = context.Request; - var response = context.Response; - var localPath = context.Request.Path.ToString(); - - var req = new WebSocketSharpRequest(request, response, request.Path, Logger); - await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false); - } + public Task ExecuteHttpHandlerAsync(HttpContext context, Func next) + => HttpServer.RequestHandler(context); /// /// Registers resources that classes will depend on @@ -777,7 +751,7 @@ namespace Emby.Server.Implementations NetworkManager, JsonSerializer, XmlSerializer, - CreateHttpListener()) + LoggerFactory) { GlobalResponse = LocalizationManager.GetLocalizedString("StartupEmbyServerIsLoading") }; @@ -1194,8 +1168,6 @@ namespace Emby.Server.Implementations }); } - protected IHttpListener CreateHttpListener() => new WebSocketSharpListener(Logger); - private CertificateInfo GetCertificateInfo(bool generateCertificate) { // Custom cert diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index b0126f7fa5..4baf96ab51 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -7,11 +7,12 @@ using System.Diagnostics; using System.IO; using System.Linq; using System.Net.Sockets; +using System.Net.WebSockets; using System.Reflection; using System.Threading; using System.Threading.Tasks; -using Emby.Server.Implementations.Net; using Emby.Server.Implementations.Services; +using Emby.Server.Implementations.SocketSharp; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; @@ -21,9 +22,11 @@ using MediaBrowser.Model.Events; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.WebUtilities; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using Microsoft.Net.Http.Headers; using ServiceStack.Text.Jsv; namespace Emby.Server.Implementations.HttpServer @@ -31,18 +34,17 @@ namespace Emby.Server.Implementations.HttpServer public class HttpListenerHost : IHttpServer, IDisposable { private readonly ILogger _logger; + private readonly ILoggerFactory _loggerFactory; private readonly IServerConfigurationManager _config; private readonly INetworkManager _networkManager; private readonly IServerApplicationHost _appHost; private readonly IJsonSerializer _jsonSerializer; private readonly IXmlSerializer _xmlSerializer; - private readonly IHttpListener _socketListener; private readonly Func> _funcParseFn; private readonly string _defaultRedirectPath; private readonly string _baseUrlPrefix; private readonly Dictionary ServiceOperationsMap = new Dictionary(); private IWebSocketListener[] _webSocketListeners = Array.Empty(); - private readonly List _webSocketConnections = new List(); private bool _disposed = false; public HttpListenerHost( @@ -53,7 +55,7 @@ namespace Emby.Server.Implementations.HttpServer INetworkManager networkManager, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, - IHttpListener socketListener) + ILoggerFactory loggerFactory) { _appHost = applicationHost; _logger = logger; @@ -63,8 +65,7 @@ namespace Emby.Server.Implementations.HttpServer _networkManager = networkManager; _jsonSerializer = jsonSerializer; _xmlSerializer = xmlSerializer; - _socketListener = socketListener; - _socketListener.WebSocketConnected = OnWebSocketConnected; + _loggerFactory = loggerFactory; _funcParseFn = t => s => JsvReader.GetParseFn(t)(s); @@ -155,38 +156,6 @@ namespace Emby.Server.Implementations.HttpServer return attributes; } - private void OnWebSocketConnected(WebSocketConnectEventArgs e) - { - if (_disposed) - { - return; - } - - var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger) - { - OnReceive = ProcessWebSocketMessageReceived, - Url = e.Url, - QueryString = e.QueryString - }; - - connection.Closed += OnConnectionClosed; - - lock (_webSocketConnections) - { - _webSocketConnections.Add(connection); - } - - WebSocketConnected?.Invoke(this, new GenericEventArgs(connection)); - } - - private void OnConnectionClosed(object sender, EventArgs e) - { - lock (_webSocketConnections) - { - _webSocketConnections.Remove((IWebSocketConnection)sender); - } - } - private static Exception GetActualException(Exception ex) { if (ex is AggregateException agg) @@ -274,32 +243,6 @@ namespace Emby.Server.Implementations.HttpServer return msg; } - /// - /// Shut down the Web Service - /// - public void Stop() - { - List connections; - - lock (_webSocketConnections) - { - connections = _webSocketConnections.ToList(); - _webSocketConnections.Clear(); - } - - foreach (var connection in connections) - { - try - { - connection.Dispose(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error disposing connection"); - } - } - } - public static string RemoveQueryStringByKey(string url, string key) { var uri = new Uri(url); @@ -411,31 +354,47 @@ namespace Emby.Server.Implementations.HttpServer private bool ValidateSsl(string remoteIp, string urlString) { - if (_config.Configuration.RequireHttps && _appHost.EnableHttps && !_config.Configuration.IsBehindProxy) + if (_config.Configuration.RequireHttps + && _appHost.EnableHttps + && !_config.Configuration.IsBehindProxy + && !urlString.Contains("https://", StringComparison.OrdinalIgnoreCase)) { - if (urlString.IndexOf("https://", StringComparison.OrdinalIgnoreCase) == -1) + // These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected + if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1 + || urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1) { - // These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected - if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1 - || urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1) - { - return true; - } + return true; + } - if (!_networkManager.IsInLocalNetwork(remoteIp)) - { - return false; - } + if (!_networkManager.IsInLocalNetwork(remoteIp)) + { + return false; } } return true; } + /// + public Task RequestHandler(HttpContext context) + { + if (context.WebSockets.IsWebSocketRequest) + { + return WebSocketRequestHandler(context); + } + + var request = context.Request; + var response = context.Response; + var localPath = context.Request.Path.ToString(); + + var req = new WebSocketSharpRequest(request, response, request.Path, _logger); + return RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted); + } + /// - /// Overridable method that can be used to implement a custom hnandler + /// Overridable method that can be used to implement a custom handler /// - public async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken) + private async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken) { var stopWatch = new Stopwatch(); stopWatch.Start(); @@ -552,6 +511,44 @@ namespace Emby.Server.Implementations.HttpServer } } + private async Task WebSocketRequestHandler(HttpContext context) + { + if (_disposed) + { + return; + } + + var url = context.Request.GetDisplayUrl(); + _logger.LogInformation("WS {Url}. UserAgent: {UserAgent}", url, context.Request.Headers[HeaderNames.UserAgent].ToString()); + + try + { + var webSocket = await context.WebSockets.AcceptWebSocketAsync(null).ConfigureAwait(false); + + var connection = new WebSocketConnection( + _loggerFactory.CreateLogger(), + webSocket, + context.Connection.RemoteIpAddress) + { + Url = url, + QueryString = context.Request.Query, + OnReceive = ProcessWebSocketMessageReceived + }; + + WebSocketConnected?.Invoke(this, new GenericEventArgs(connection)); + + await connection.ProcessAsync().ConfigureAwait(false); + } + catch (WebSocketException ex) + { + _logger.LogError(ex, "ProcessWebSocketRequest error"); + if (!context.Response.HasStarted) + { + context.Response.StatusCode = 500; + } + } + } + // Entry point for HttpListener public ServiceHandler GetServiceHandler(IHttpRequest httpReq) { @@ -661,11 +658,6 @@ namespace Emby.Server.Implementations.HttpServer return _jsonSerializer.DeserializeFromStreamAsync(stream, type); } - public Task ProcessWebSocketRequest(HttpContext context) - { - return _socketListener.ProcessWebSocketRequest(context); - } - private string NormalizeEmbyRoutePath(string path) { _logger.LogDebug("Normalizing /emby route"); @@ -697,7 +689,7 @@ namespace Emby.Server.Implementations.HttpServer if (disposing) { - Stop(); + // TODO: } _disposed = true; diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs deleted file mode 100644 index 1c3496e5d5..0000000000 --- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs +++ /dev/null @@ -1,40 +0,0 @@ -#pragma warning disable CS1591 -#pragma warning disable SA1600 - -using System; -using System.Threading; -using System.Threading.Tasks; -using Emby.Server.Implementations.Net; -using MediaBrowser.Model.Services; -using Microsoft.AspNetCore.Http; - -namespace Emby.Server.Implementations.HttpServer -{ - public interface IHttpListener : IDisposable - { - /// - /// Gets or sets the error handler. - /// - /// The error handler. - Func ErrorHandler { get; set; } - - /// - /// Gets or sets the request handler. - /// - /// The request handler. - Func RequestHandler { get; set; } - - /// - /// Gets or sets the web socket handler. - /// - /// The web socket handler. - Action WebSocketConnected { get; set; } - - /// - /// Stops this instance. - /// - Task Stop(); - - Task ProcessWebSocketRequest(HttpContext ctx); - } -} diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 2292d86a4a..b4f420e5d2 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -1,15 +1,16 @@ using System; +using System.Buffers; +using System.IO.Pipelines; +using System.Net; using System.Net.WebSockets; -using System.Text; +using System.Text.Json; using System.Threading; using System.Threading.Tasks; -using Emby.Server.Implementations.Net; +using MediaBrowser.Common.Json; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Net; -using MediaBrowser.Model.Serialization; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; -using UtfUnknown; namespace Emby.Server.Implementations.HttpServer { @@ -24,54 +25,46 @@ namespace Emby.Server.Implementations.HttpServer private readonly ILogger _logger; /// - /// The json serializer. + /// The json serializer options. /// - private readonly IJsonSerializer _jsonSerializer; + private readonly JsonSerializerOptions _jsonOptions; /// /// The socket. /// - private readonly IWebSocket _socket; + private readonly WebSocket _socket; + + private bool _disposed = false; /// /// Initializes a new instance of the class. /// /// The socket. /// The remote end point. - /// The json serializer. /// The logger. /// socket - public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger) + public WebSocketConnection(ILogger logger, WebSocket socket, IPAddress remoteEndPoint) { if (socket == null) { throw new ArgumentNullException(nameof(socket)); } - if (string.IsNullOrEmpty(remoteEndPoint)) + if (remoteEndPoint != null) { throw new ArgumentNullException(nameof(remoteEndPoint)); } - if (jsonSerializer == null) - { - throw new ArgumentNullException(nameof(jsonSerializer)); - } - if (logger == null) { throw new ArgumentNullException(nameof(logger)); } - Id = Guid.NewGuid(); - _jsonSerializer = jsonSerializer; _socket = socket; - _socket.OnReceiveBytes = OnReceiveInternal; - RemoteEndPoint = remoteEndPoint; _logger = logger; - socket.Closed += OnSocketClosed; + _jsonOptions = JsonDefaults.GetOptions(); } /// @@ -80,7 +73,7 @@ namespace Emby.Server.Implementations.HttpServer /// /// Gets or sets the remote end point. /// - public string RemoteEndPoint { get; private set; } + public IPAddress RemoteEndPoint { get; private set; } /// /// Gets or sets the receive action. @@ -94,12 +87,6 @@ namespace Emby.Server.Implementations.HttpServer /// The last activity date. public DateTime LastActivityDate { get; private set; } - /// - /// Gets the id. - /// - /// The id. - public Guid Id { get; private set; } - /// /// Gets or sets the URL. /// @@ -118,46 +105,78 @@ namespace Emby.Server.Implementations.HttpServer /// The state. public WebSocketState State => _socket.State; - void OnSocketClosed(object sender, EventArgs e) - { - Closed?.Invoke(this, EventArgs.Empty); - } - /// - /// Called when [receive]. + /// Sends a message asynchronously. /// - /// The bytes. - private void OnReceiveInternal(byte[] bytes) + /// + /// The message. + /// The cancellation token. + /// Task. + /// message + public Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken) { - LastActivityDate = DateTime.UtcNow; - - if (OnReceive == null) + if (message == null) { - return; + throw new ArgumentNullException(nameof(message)); } - var charset = CharsetDetector.DetectFromBytes(bytes).Detected?.EncodingName; - if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase)) + var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions); + return _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken); + } + + /// + public async Task ProcessAsync(CancellationToken cancellationToken = default) + { + var pipe = new Pipe(); + var writer = pipe.Writer; + + ValueWebSocketReceiveResult receiveresult; + do { - OnReceiveInternal(Encoding.UTF8.GetString(bytes, 0, bytes.Length)); - } - else + // Allocate at least 512 bytes from the PipeWriter + Memory memory = writer.GetMemory(512); + + receiveresult = await _socket.ReceiveAsync(memory, cancellationToken); + int bytesRead = receiveresult.Count; + if (bytesRead == 0) + { + continue; + } + + // Tell the PipeWriter how much was read from the Socket + writer.Advance(bytesRead); + + // Make the data available to the PipeReader + FlushResult flushResult = await writer.FlushAsync(); + if (flushResult.IsCompleted) + { + // The PipeReader stopped reading + break; + } + + if (receiveresult.EndOfMessage) + { + await ProcessInternal(pipe.Reader).ConfigureAwait(false); + } + } while (_socket.State == WebSocketState.Open && receiveresult.MessageType != WebSocketMessageType.Close); + + if (_socket.State == WebSocketState.Open) { - OnReceiveInternal(Encoding.ASCII.GetString(bytes, 0, bytes.Length)); + await _socket.CloseAsync( + WebSocketCloseStatus.NormalClosure, + string.Empty, // REVIEW: human readable explanation as to why the connection is closed. + cancellationToken).ConfigureAwait(false); } + + Closed?.Invoke(this, EventArgs.Empty); + + _socket.Dispose(); } - private void OnReceiveInternal(string message) + private async Task ProcessInternal(PipeReader reader) { LastActivityDate = DateTime.UtcNow; - if (!message.StartsWith("{", StringComparison.OrdinalIgnoreCase)) - { - // This info is useful sometimes but also clogs up the log - _logger.LogDebug("Received web socket message that is not a json structure: {message}", message); - return; - } - if (OnReceive == null) { return; @@ -165,74 +184,47 @@ namespace Emby.Server.Implementations.HttpServer try { - var stub = (WebSocketMessage)_jsonSerializer.DeserializeFromString(message, typeof(WebSocketMessage)); + var result = await reader.ReadAsync().ConfigureAwait(false); + if (!result.IsCompleted) + { + return; + } + + WebSocketMessage stub; + var buffer = result.Buffer; + if (buffer.IsSingleSegment) + { + stub = JsonSerializer.Deserialize>(buffer.FirstSpan, _jsonOptions); + } + else + { + var buf = ArrayPool.Shared.Rent(Convert.ToInt32(buffer.Length)); + try + { + buffer.CopyTo(buf); + stub = JsonSerializer.Deserialize>(buf, _jsonOptions); + } + finally + { + ArrayPool.Shared.Return(buf); + } + } var info = new WebSocketMessageInfo { MessageType = stub.MessageType, - Data = stub.Data?.ToString(), + Data = stub.Data.ToString(), Connection = this }; - OnReceive(info); + await OnReceive(info).ConfigureAwait(false); } - catch (Exception ex) + catch (JsonException ex) { _logger.LogError(ex, "Error processing web socket message"); } } - /// - /// Sends a message asynchronously. - /// - /// - /// The message. - /// The cancellation token. - /// Task. - /// message - public Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - var json = _jsonSerializer.SerializeToString(message); - - return SendAsync(json, cancellationToken); - } - - /// - /// Sends a message asynchronously. - /// - /// The buffer. - /// The cancellation token. - /// Task. - public Task SendAsync(byte[] buffer, CancellationToken cancellationToken) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); - } - - cancellationToken.ThrowIfCancellationRequested(); - - return _socket.SendAsync(buffer, true, cancellationToken); - } - - /// - public Task SendAsync(string text, CancellationToken cancellationToken) - { - if (string.IsNullOrEmpty(text)) - { - throw new ArgumentNullException(nameof(text)); - } - - cancellationToken.ThrowIfCancellationRequested(); - - return _socket.SendAsync(text, true, cancellationToken); - } - /// public void Dispose() { @@ -246,10 +238,17 @@ namespace Emby.Server.Implementations.HttpServer /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool dispose) { + if (_disposed) + { + return; + } + if (dispose) { _socket.Dispose(); } + + _disposed = true; } } } diff --git a/Emby.Server.Implementations/Net/IWebSocket.cs b/Emby.Server.Implementations/Net/IWebSocket.cs deleted file mode 100644 index 4d160aa66f..0000000000 --- a/Emby.Server.Implementations/Net/IWebSocket.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Net.WebSockets; -using System.Threading; -using System.Threading.Tasks; - -namespace Emby.Server.Implementations.Net -{ - /// - /// Interface IWebSocket - /// - public interface IWebSocket : IDisposable - { - /// - /// Occurs when [closed]. - /// - event EventHandler Closed; - - /// - /// Gets or sets the state. - /// - /// The state. - WebSocketState State { get; } - - /// - /// Gets or sets the receive action. - /// - /// The receive action. - Action OnReceiveBytes { get; set; } - - /// - /// Sends the async. - /// - /// The bytes. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken); - - /// - /// Sends the asynchronous. - /// - /// The text. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken); - } -} diff --git a/Emby.Server.Implementations/Net/WebSocketConnectEventArgs.cs b/Emby.Server.Implementations/Net/WebSocketConnectEventArgs.cs deleted file mode 100644 index e3047d3926..0000000000 --- a/Emby.Server.Implementations/Net/WebSocketConnectEventArgs.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Net.WebSockets; -using MediaBrowser.Model.Services; -using Microsoft.AspNetCore.Http; - -namespace Emby.Server.Implementations.Net -{ - public class WebSocketConnectEventArgs : EventArgs - { - /// - /// Gets or sets the URL. - /// - /// The URL. - public string Url { get; set; } - /// - /// Gets or sets the query string. - /// - /// The query string. - public IQueryCollection QueryString { get; set; } - /// - /// Gets or sets the web socket. - /// - /// The web socket. - public IWebSocket WebSocket { get; set; } - /// - /// Gets or sets the endpoint. - /// - /// The endpoint. - public string Endpoint { get; set; } - } -} diff --git a/Emby.Server.Implementations/Session/HttpSessionController.cs b/Emby.Server.Implementations/Session/HttpSessionController.cs deleted file mode 100644 index dfb81816c7..0000000000 --- a/Emby.Server.Implementations/Session/HttpSessionController.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Net; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Serialization; -using MediaBrowser.Model.Session; - -namespace Emby.Server.Implementations.Session -{ - public class HttpSessionController : ISessionController - { - private readonly IHttpClient _httpClient; - private readonly IJsonSerializer _json; - private readonly ISessionManager _sessionManager; - - public SessionInfo Session { get; private set; } - - private readonly string _postUrl; - - public HttpSessionController(IHttpClient httpClient, - IJsonSerializer json, - SessionInfo session, - string postUrl, ISessionManager sessionManager) - { - _httpClient = httpClient; - _json = json; - Session = session; - _postUrl = postUrl; - _sessionManager = sessionManager; - } - - private string PostUrl => string.Format("http://{0}{1}", Session.RemoteEndPoint, _postUrl); - - public bool IsSessionActive => (DateTime.UtcNow - Session.LastActivityDate).TotalMinutes <= 5; - - public bool SupportsMediaControl => true; - - private Task SendMessage(string name, string messageId, CancellationToken cancellationToken) - { - return SendMessage(name, messageId, new Dictionary(), cancellationToken); - } - - private Task SendMessage(string name, string messageId, Dictionary args, CancellationToken cancellationToken) - { - args["messageId"] = messageId; - var url = PostUrl + "/" + name + ToQueryString(args); - - return SendRequest(new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken, - BufferContent = false - }); - } - - private Task SendPlayCommand(PlayRequest command, string messageId, CancellationToken cancellationToken) - { - var dict = new Dictionary(); - - dict["ItemIds"] = string.Join(",", command.ItemIds.Select(i => i.ToString("N", CultureInfo.InvariantCulture)).ToArray()); - - if (command.StartPositionTicks.HasValue) - { - dict["StartPositionTicks"] = command.StartPositionTicks.Value.ToString(CultureInfo.InvariantCulture); - } - if (command.AudioStreamIndex.HasValue) - { - dict["AudioStreamIndex"] = command.AudioStreamIndex.Value.ToString(CultureInfo.InvariantCulture); - } - if (command.SubtitleStreamIndex.HasValue) - { - dict["SubtitleStreamIndex"] = command.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture); - } - if (command.StartIndex.HasValue) - { - dict["StartIndex"] = command.StartIndex.Value.ToString(CultureInfo.InvariantCulture); - } - if (!string.IsNullOrEmpty(command.MediaSourceId)) - { - dict["MediaSourceId"] = command.MediaSourceId; - } - - return SendMessage(command.PlayCommand.ToString(), messageId, dict, cancellationToken); - } - - private Task SendPlaystateCommand(PlaystateRequest command, string messageId, CancellationToken cancellationToken) - { - var args = new Dictionary(); - - if (command.Command == PlaystateCommand.Seek) - { - if (!command.SeekPositionTicks.HasValue) - { - throw new ArgumentException("SeekPositionTicks cannot be null"); - } - - args["SeekPositionTicks"] = command.SeekPositionTicks.Value.ToString(CultureInfo.InvariantCulture); - } - - return SendMessage(command.Command.ToString(), messageId, args, cancellationToken); - } - - private string[] _supportedMessages = Array.Empty(); - public Task SendMessage(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken) - { - if (!IsSessionActive) - { - return Task.CompletedTask; - } - - if (string.Equals(name, "Play", StringComparison.OrdinalIgnoreCase)) - { - return SendPlayCommand(data as PlayRequest, messageId, cancellationToken); - } - if (string.Equals(name, "PlayState", StringComparison.OrdinalIgnoreCase)) - { - return SendPlaystateCommand(data as PlaystateRequest, messageId, cancellationToken); - } - if (string.Equals(name, "GeneralCommand", StringComparison.OrdinalIgnoreCase)) - { - var command = data as GeneralCommand; - return SendMessage(command.Name, messageId, command.Arguments, cancellationToken); - } - - if (!_supportedMessages.Contains(name, StringComparer.OrdinalIgnoreCase)) - { - return Task.CompletedTask; - } - - var url = PostUrl + "/" + name; - - url += "?messageId=" + messageId; - - var options = new HttpRequestOptions - { - Url = url, - CancellationToken = cancellationToken, - BufferContent = false - }; - - if (data != null) - { - if (typeof(T) == typeof(string)) - { - var str = data as string; - if (!string.IsNullOrEmpty(str)) - { - options.RequestContent = str; - options.RequestContentType = "application/json"; - } - } - else - { - options.RequestContent = _json.SerializeToString(data); - options.RequestContentType = "application/json"; - } - } - - return SendRequest(options); - } - - private async Task SendRequest(HttpRequestOptions options) - { - using (var response = await _httpClient.Post(options).ConfigureAwait(false)) - { - - } - } - - private static string ToQueryString(Dictionary nvc) - { - var array = (from item in nvc - select string.Format("{0}={1}", WebUtility.UrlEncode(item.Key), WebUtility.UrlEncode(item.Value))) - .ToArray(); - - var args = string.Join("&", array); - - if (string.IsNullOrEmpty(args)) - { - return args; - } - - return "?" + args; - } - } -} diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index b1d513dd4f..db00ceeb71 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -463,8 +463,7 @@ namespace Emby.Server.Implementations.Session Client = appName, DeviceId = deviceId, ApplicationVersion = appVersion, - Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture), - ServerId = _appHost.SystemId + Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture) }; var username = user?.Name; @@ -1024,12 +1023,12 @@ namespace Emby.Server.Implementations.Session private static async Task SendMessageToSession(SessionInfo session, string name, T data, CancellationToken cancellationToken) { - var controllers = session.SessionControllers.ToArray(); - var messageId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); + var controllers = session.SessionControllers; + var messageId = Guid.NewGuid(); foreach (var controller in controllers) { - await controller.SendMessage(name, messageId, data, controllers, cancellationToken).ConfigureAwait(false); + await controller.SendMessage(name, messageId, data, cancellationToken).ConfigureAwait(false); } } @@ -1037,13 +1036,13 @@ namespace Emby.Server.Implementations.Session { IEnumerable GetTasks() { - var messageId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); + var messageId = Guid.NewGuid(); foreach (var session in sessions) { var controllers = session.SessionControllers; foreach (var controller in controllers) { - yield return controller.SendMessage(name, messageId, data, controllers, cancellationToken); + yield return controller.SendMessage(name, messageId, data, cancellationToken); } } } diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs index 930f2d35d3..13b42698d3 100644 --- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs @@ -3,7 +3,6 @@ using System.Threading.Tasks; using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Events; -using MediaBrowser.Model.Serialization; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; @@ -12,7 +11,7 @@ namespace Emby.Server.Implementations.Session /// /// Class SessionWebSocketListener /// - public class SessionWebSocketListener : IWebSocketListener, IDisposable + public sealed class SessionWebSocketListener : IWebSocketListener, IDisposable { /// /// The _session manager @@ -23,35 +22,34 @@ namespace Emby.Server.Implementations.Session /// The _logger /// private readonly ILogger _logger; - - /// - /// The _dto service - /// - private readonly IJsonSerializer _json; + private readonly ILoggerFactory _loggerFactory; private readonly IHttpServer _httpServer; - /// /// Initializes a new instance of the class. /// + /// The logger. /// The session manager. /// The logger factory. - /// The json. /// The HTTP server. - public SessionWebSocketListener(ISessionManager sessionManager, ILoggerFactory loggerFactory, IJsonSerializer json, IHttpServer httpServer) + public SessionWebSocketListener( + ILogger logger, + ISessionManager sessionManager, + ILoggerFactory loggerFactory, + IHttpServer httpServer) { + _logger = logger; _sessionManager = sessionManager; - _logger = loggerFactory.CreateLogger(GetType().Name); - _json = json; + _loggerFactory = loggerFactory; _httpServer = httpServer; - httpServer.WebSocketConnected += _serverManager_WebSocketConnected; + + httpServer.WebSocketConnected += OnServerManagerWebSocketConnected; } - void _serverManager_WebSocketConnected(object sender, GenericEventArgs e) + private void OnServerManagerWebSocketConnected(object sender, GenericEventArgs e) { - var session = GetSession(e.Argument.QueryString, e.Argument.RemoteEndPoint); - + var session = GetSession(e.Argument.QueryString, e.Argument.RemoteEndPoint.ToString()); if (session != null) { EnsureController(session, e.Argument); @@ -79,9 +77,10 @@ namespace Emby.Server.Implementations.Session return _sessionManager.GetSessionByAuthenticationToken(token, deviceId, remoteEndpoint); } + /// public void Dispose() { - _httpServer.WebSocketConnected -= _serverManager_WebSocketConnected; + _httpServer.WebSocketConnected -= OnServerManagerWebSocketConnected; } /// @@ -94,7 +93,8 @@ namespace Emby.Server.Implementations.Session private void EnsureController(SessionInfo session, IWebSocketConnection connection) { - var controllerInfo = session.EnsureController(s => new WebSocketController(s, _logger, _sessionManager)); + var controllerInfo = session.EnsureController( + s => new WebSocketController(_loggerFactory.CreateLogger(), s, _sessionManager)); var controller = (WebSocketController)controllerInfo.Item1; controller.AddWebSocket(connection); diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index 0d483c55fa..c17e67da93 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -11,60 +11,64 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Session { - public class WebSocketController : ISessionController, IDisposable + public sealed class WebSocketController : ISessionController, IDisposable { - public SessionInfo Session { get; private set; } - public IReadOnlyList Sockets { get; private set; } - private readonly ILogger _logger; - private readonly ISessionManager _sessionManager; + private readonly SessionInfo _session; - public WebSocketController(SessionInfo session, ILogger logger, ISessionManager sessionManager) + private List _sockets; + private bool _disposed = false; + + public WebSocketController( + ILogger logger, + SessionInfo session, + ISessionManager sessionManager) { - Session = session; _logger = logger; + _session = session; _sessionManager = sessionManager; - Sockets = new List(); + _sockets = new List(); } private bool HasOpenSockets => GetActiveSockets().Any(); + /// public bool SupportsMediaControl => HasOpenSockets; + /// public bool IsSessionActive => HasOpenSockets; private IEnumerable GetActiveSockets() - { - return Sockets - .OrderByDescending(i => i.LastActivityDate) - .Where(i => i.State == WebSocketState.Open); - } + => _sockets.Where(i => i.State == WebSocketState.Open); + /// public void AddWebSocket(IWebSocketConnection connection) { - var sockets = Sockets.ToList(); - sockets.Add(connection); + _logger.LogDebug("Adding websocket to session {Session}", _session.Id); + _sockets.Add(connection); - Sockets = sockets; - - connection.Closed += connection_Closed; + connection.Closed += OnConnectionClosed; } - void connection_Closed(object sender, EventArgs e) + private void OnConnectionClosed(object sender, EventArgs e) { + _logger.LogDebug("Removing websocket from session {Session}", _session.Id); var connection = (IWebSocketConnection)sender; - var sockets = Sockets.ToList(); - sockets.Remove(connection); - - Sockets = sockets; - - _sessionManager.CloseIfNeeded(Session); + _sockets.Remove(connection); + _sessionManager.CloseIfNeeded(_session); + connection.Dispose(); } - public Task SendMessage(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken) + /// + public Task SendMessage( + string name, + Guid messageId, + T data, + CancellationToken cancellationToken) { var socket = GetActiveSockets() + .OrderByDescending(i => i.LastActivityDate) .FirstOrDefault(); if (socket == null) @@ -77,16 +81,24 @@ namespace Emby.Server.Implementations.Session Data = data, MessageType = name, MessageId = messageId - }, cancellationToken); } + /// public void Dispose() { - foreach (var socket in Sockets.ToList()) + if (_disposed) { - socket.Closed -= connection_Closed; + return; } + + foreach (var socket in _sockets) + { + socket.Closed -= OnConnectionClosed; + socket.Dispose(); + } + + _disposed = true; } } } diff --git a/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs b/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs deleted file mode 100644 index 67521d6c63..0000000000 --- a/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Net.WebSockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using Emby.Server.Implementations.Net; -using Microsoft.Extensions.Logging; - -namespace Emby.Server.Implementations.SocketSharp -{ - public class SharpWebSocket : IWebSocket - { - /// - /// The logger - /// - private readonly ILogger _logger; - - public event EventHandler Closed; - - /// - /// Gets or sets the web socket. - /// - /// The web socket. - private readonly WebSocket _webSocket; - - private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); - private bool _disposed; - - public SharpWebSocket(WebSocket socket, ILogger logger) - { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - _webSocket = socket ?? throw new ArgumentNullException(nameof(socket)); - } - - /// - /// Gets the state. - /// - /// The state. - public WebSocketState State => _webSocket.State; - - /// - /// Sends the async. - /// - /// The bytes. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - public Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken) - { - return _webSocket.SendAsync(new ArraySegment(bytes), WebSocketMessageType.Binary, endOfMessage, cancellationToken); - } - - /// - /// Sends the asynchronous. - /// - /// The text. - /// if set to true [end of message]. - /// The cancellation token. - /// Task. - public Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken) - { - return _webSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(text)), WebSocketMessageType.Text, endOfMessage, cancellationToken); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (_disposed) - { - return; - } - - if (dispose) - { - _cancellationTokenSource.Cancel(); - if (_webSocket.State == WebSocketState.Open) - { - _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by client", - CancellationToken.None); - } - Closed?.Invoke(this, EventArgs.Empty); - } - - _disposed = true; - } - - /// - /// Gets or sets the receive action. - /// - /// The receive action. - public Action OnReceiveBytes { get; set; } - } -} diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs deleted file mode 100644 index ba5ba1904c..0000000000 --- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.WebSockets; -using System.Threading; -using System.Threading.Tasks; -using Emby.Server.Implementations.HttpServer; -using Emby.Server.Implementations.Net; -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Services; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; -using Microsoft.Extensions.Logging; -using Microsoft.Net.Http.Headers; - -namespace Emby.Server.Implementations.SocketSharp -{ - public class WebSocketSharpListener : IHttpListener - { - private readonly ILogger _logger; - - private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); - private CancellationToken _disposeCancellationToken; - - public WebSocketSharpListener( - ILogger logger) - { - _logger = logger; - - _disposeCancellationToken = _disposeCancellationTokenSource.Token; - } - - public Func ErrorHandler { get; set; } - public Func RequestHandler { get; set; } - - public Action WebSocketConnected { get; set; } - - private static void LogRequest(ILogger logger, HttpRequest request) - { - var url = request.GetDisplayUrl(); - - logger.LogInformation("WS {Url}. UserAgent: {UserAgent}", url, request.Headers[HeaderNames.UserAgent].ToString()); - } - - public async Task ProcessWebSocketRequest(HttpContext ctx) - { - try - { - LogRequest(_logger, ctx.Request); - var endpoint = ctx.Connection.RemoteIpAddress.ToString(); - var url = ctx.Request.GetDisplayUrl(); - - var webSocketContext = await ctx.WebSockets.AcceptWebSocketAsync(null).ConfigureAwait(false); - var socket = new SharpWebSocket(webSocketContext, _logger); - - WebSocketConnected(new WebSocketConnectEventArgs - { - Url = url, - QueryString = ctx.Request.Query, - WebSocket = socket, - Endpoint = endpoint - }); - - WebSocketReceiveResult result; - var message = new List(); - - do - { - var buffer = WebSocket.CreateServerBuffer(4096); - result = await webSocketContext.ReceiveAsync(buffer, _disposeCancellationToken); - message.AddRange(buffer.Array.Take(result.Count)); - - if (result.EndOfMessage) - { - socket.OnReceiveBytes(message.ToArray()); - message.Clear(); - } - } while (socket.State == WebSocketState.Open && result.MessageType != WebSocketMessageType.Close); - - - if (webSocketContext.State == WebSocketState.Open) - { - await webSocketContext.CloseAsync( - result.CloseStatus ?? WebSocketCloseStatus.NormalClosure, - result.CloseStatusDescription, - _disposeCancellationToken).ConfigureAwait(false); - } - - socket.Dispose(); - } - catch (Exception ex) - { - _logger.LogError(ex, "AcceptWebSocketAsync error"); - if (!ctx.Response.HasStarted) - { - ctx.Response.StatusCode = 500; - } - } - } - - public Task Stop() - { - _disposeCancellationTokenSource.Cancel(); - return Task.CompletedTask; - } - - /// - /// Releases the unmanaged resources and disposes of the managed resources used. - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private bool _disposed; - - /// - /// Releases the unmanaged resources and disposes of the managed resources used. - /// - /// Whether or not the managed resources should be disposed. - protected virtual void Dispose(bool disposing) - { - if (_disposed) - { - return; - } - - if (disposing) - { - Stop().GetAwaiter().GetResult(); - } - - _disposed = true; - } - } -} diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 3ee5fb8b50..45f2b9d7c2 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -3,7 +3,6 @@ using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -64,7 +63,6 @@ namespace Jellyfin.Server app.UseResponseCompression(); // TODO app.UseMiddleware(); - app.Use(serverApplicationHost.ExecuteWebsocketHandlerAsync); // TODO use when old API is removed: app.UseAuthentication(); app.UseJellyfinApiSwagger(); diff --git a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs index f1a6622fb5..cf7ddd6319 100644 --- a/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/Session/SessionInfoWebSocketListener.cs @@ -31,46 +31,46 @@ namespace MediaBrowser.Api.Session { _sessionManager = sessionManager; - _sessionManager.SessionStarted += _sessionManager_SessionStarted; - _sessionManager.SessionEnded += _sessionManager_SessionEnded; - _sessionManager.PlaybackStart += _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped += _sessionManager_PlaybackStopped; - _sessionManager.PlaybackProgress += _sessionManager_PlaybackProgress; - _sessionManager.CapabilitiesChanged += _sessionManager_CapabilitiesChanged; - _sessionManager.SessionActivity += _sessionManager_SessionActivity; + _sessionManager.SessionStarted += OnSessionManagerSessionStarted; + _sessionManager.SessionEnded += OnSessionManagerSessionEnded; + _sessionManager.PlaybackStart += OnSessionManagerPlaybackStart; + _sessionManager.PlaybackStopped += OnSessionManagerPlaybackStopped; + _sessionManager.PlaybackProgress += OnSessionManagerPlaybackProgress; + _sessionManager.CapabilitiesChanged += OnSessionManagerCapabilitiesChanged; + _sessionManager.SessionActivity += OnSessionManagerSessionActivity; } - void _sessionManager_SessionActivity(object sender, SessionEventArgs e) + private void OnSessionManagerSessionActivity(object sender, SessionEventArgs e) { SendData(false); } - void _sessionManager_CapabilitiesChanged(object sender, SessionEventArgs e) + private void OnSessionManagerCapabilitiesChanged(object sender, SessionEventArgs e) { SendData(true); } - void _sessionManager_PlaybackProgress(object sender, PlaybackProgressEventArgs e) + private void OnSessionManagerPlaybackProgress(object sender, PlaybackProgressEventArgs e) { SendData(!e.IsAutomated); } - void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) + private void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e) { SendData(true); } - void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e) + private void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e) { SendData(true); } - void _sessionManager_SessionEnded(object sender, SessionEventArgs e) + private void OnSessionManagerSessionEnded(object sender, SessionEventArgs e) { SendData(true); } - void _sessionManager_SessionStarted(object sender, SessionEventArgs e) + private void OnSessionManagerSessionStarted(object sender, SessionEventArgs e) { SendData(true); } @@ -84,15 +84,16 @@ namespace MediaBrowser.Api.Session return Task.FromResult(_sessionManager.Sessions); } + /// protected override void Dispose(bool dispose) { - _sessionManager.SessionStarted -= _sessionManager_SessionStarted; - _sessionManager.SessionEnded -= _sessionManager_SessionEnded; - _sessionManager.PlaybackStart -= _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped -= _sessionManager_PlaybackStopped; - _sessionManager.PlaybackProgress -= _sessionManager_PlaybackProgress; - _sessionManager.CapabilitiesChanged -= _sessionManager_CapabilitiesChanged; - _sessionManager.SessionActivity -= _sessionManager_SessionActivity; + _sessionManager.SessionStarted -= OnSessionManagerSessionStarted; + _sessionManager.SessionEnded -= OnSessionManagerSessionEnded; + _sessionManager.PlaybackStart -= OnSessionManagerPlaybackStart; + _sessionManager.PlaybackStopped -= OnSessionManagerPlaybackStopped; + _sessionManager.PlaybackProgress -= OnSessionManagerPlaybackProgress; + _sessionManager.CapabilitiesChanged -= OnSessionManagerCapabilitiesChanged; + _sessionManager.SessionActivity -= OnSessionManagerSessionActivity; base.Dispose(dispose); } diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 25f0905eb8..0790b6cd60 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -92,7 +92,5 @@ namespace MediaBrowser.Controller string ReverseVirtualPath(string path); Task ExecuteHttpHandlerAsync(HttpContext context, Func next); - - Task ExecuteWebsocketHandlerAsync(HttpContext context, Func next); } } diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index ee5c1a165a..9d71426d88 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -154,7 +154,6 @@ namespace MediaBrowser.Controller.Net { MessageType = Name, Data = data - }, cancellationToken).ConfigureAwait(false); state.DateLastSendUtc = DateTime.UtcNow; diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index 46933c0465..694e3954ed 100644 --- a/MediaBrowser.Controller/Net/IHttpServer.cs +++ b/MediaBrowser.Controller/Net/IHttpServer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Events; using MediaBrowser.Model.Services; @@ -19,11 +18,6 @@ namespace MediaBrowser.Controller.Net /// The URL prefix. string[] UrlPrefixes { get; } - /// - /// Stops this instance. - /// - void Stop(); - /// /// Occurs when [web socket connected]. /// @@ -39,23 +33,11 @@ namespace MediaBrowser.Controller.Net /// string GlobalResponse { get; set; } - /// - /// Sends the http context to the socket listener - /// - /// - /// - Task ProcessWebSocketRequest(HttpContext ctx); - /// /// The HTTP request handler /// - /// - /// - /// - /// - /// + /// /// - Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, - CancellationToken cancellationToken); + Task RequestHandler(HttpContext context); } } diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index 566897b31f..e2a714d5b1 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -1,9 +1,9 @@ using System; +using System.Net; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Model.Net; -using MediaBrowser.Model.Services; using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net @@ -15,12 +15,6 @@ namespace MediaBrowser.Controller.Net /// event EventHandler Closed; - /// - /// Gets the id. - /// - /// The id. - Guid Id { get; } - /// /// Gets the last activity date. /// @@ -32,6 +26,7 @@ namespace MediaBrowser.Controller.Net /// /// The URL. string Url { get; set; } + /// /// Gets or sets the query string. /// @@ -54,7 +49,7 @@ namespace MediaBrowser.Controller.Net /// Gets the remote end point. /// /// The remote end point. - string RemoteEndPoint { get; } + IPAddress RemoteEndPoint { get; } /// /// Sends a message asynchronously. @@ -66,21 +61,6 @@ namespace MediaBrowser.Controller.Net /// message Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken); - /// - /// Sends a message asynchronously. - /// - /// The buffer. - /// The cancellation token. - /// Task. - Task SendAsync(byte[] buffer, CancellationToken cancellationToken); - - /// - /// Sends a message asynchronously. - /// - /// The text. - /// The cancellation token. - /// Task. - /// buffer - Task SendAsync(string text, CancellationToken cancellationToken); + Task ProcessAsync(CancellationToken cancellationToken = default); } } diff --git a/MediaBrowser.Controller/Session/ISessionController.cs b/MediaBrowser.Controller/Session/ISessionController.cs index a59c96ac70..04450085bf 100644 --- a/MediaBrowser.Controller/Session/ISessionController.cs +++ b/MediaBrowser.Controller/Session/ISessionController.cs @@ -1,3 +1,4 @@ +using System; using System.Threading; using System.Threading.Tasks; @@ -20,6 +21,6 @@ namespace MediaBrowser.Controller.Session /// /// Sends the message. /// - Task SendMessage(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken); + Task SendMessage(string name, Guid messageId, T data, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index acda6a4166..63ed43a833 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -10,13 +10,23 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Controller.Session { /// - /// Class SessionInfo + /// Class SessionInfo. /// - public class SessionInfo : IDisposable + public sealed class SessionInfo : IDisposable { - private ISessionManager _sessionManager; + // 1 second + private const long ProgressIncrement = 10000000; + + private readonly ISessionManager _sessionManager; private readonly ILogger _logger; + + private readonly object _progressLock = new object(); + private Timer _progressTimer; + private PlaybackProgressInfo _lastProgressInfo; + + private bool _disposed = false; + public SessionInfo(ISessionManager sessionManager, ILogger logger) { _sessionManager = sessionManager; @@ -97,8 +107,6 @@ namespace MediaBrowser.Controller.Session /// The name of the device. public string DeviceName { get; set; } - public string DeviceType { get; set; } - /// /// Gets or sets the now playing item. /// @@ -126,28 +134,6 @@ namespace MediaBrowser.Controller.Session [JsonIgnore] public ISessionController[] SessionControllers { get; set; } - /// - /// Gets or sets the application icon URL. - /// - /// The application icon URL. - public string AppIconUrl { get; set; } - - /// - /// Gets or sets the supported commands. - /// - /// The supported commands. - public string[] SupportedCommands - { - get - { - if (Capabilities == null) - { - return new string[] { }; - } - return Capabilities.SupportedCommands; - } - } - public TranscodingInfo TranscodingInfo { get; set; } /// @@ -219,6 +205,14 @@ namespace MediaBrowser.Controller.Session } } + public QueueItem[] NowPlayingQueue { get; set; } + + public bool HasCustomDeviceName { get; set; } + + public string PlaylistItemId { get; set; } + + public string UserPrimaryImageTag { get; set; } + public Tuple EnsureController(Func factory) { var controllers = SessionControllers.ToList(); @@ -267,10 +261,6 @@ namespace MediaBrowser.Controller.Session return false; } - private readonly object _progressLock = new object(); - private Timer _progressTimer; - private PlaybackProgressInfo _lastProgressInfo; - public void StartAutomaticProgress(PlaybackProgressInfo progressInfo) { if (_disposed) @@ -293,9 +283,6 @@ namespace MediaBrowser.Controller.Session } } - // 1 second - private const long ProgressIncrement = 10000000; - private async void OnProgressTimerCallback(object state) { if (_disposed) @@ -354,8 +341,7 @@ namespace MediaBrowser.Controller.Session } } - private bool _disposed = false; - + /// public void Dispose() { _disposed = true; @@ -367,30 +353,12 @@ namespace MediaBrowser.Controller.Session foreach (var controller in controllers) { - var disposable = controller as IDisposable; - - if (disposable != null) + if (controller is IDisposable disposable) { _logger.LogDebug("Disposing session controller {0}", disposable.GetType().Name); - - try - { - disposable.Dispose(); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error disposing session controller"); - } + disposable.Dispose(); } } - - _sessionManager = null; } - - public QueueItem[] NowPlayingQueue { get; set; } - public bool HasCustomDeviceName { get; set; } - public string PlaylistItemId { get; set; } - public string ServerId { get; set; } - public string UserPrimaryImageTag { get; set; } } } diff --git a/MediaBrowser.Model/Net/WebSocketMessage.cs b/MediaBrowser.Model/Net/WebSocketMessage.cs index c763216f12..308032f833 100644 --- a/MediaBrowser.Model/Net/WebSocketMessage.cs +++ b/MediaBrowser.Model/Net/WebSocketMessage.cs @@ -1,3 +1,5 @@ +using System; + namespace MediaBrowser.Model.Net { /// @@ -11,13 +13,15 @@ namespace MediaBrowser.Model.Net /// /// The type of the message. public string MessageType { get; set; } - public string MessageId { get; set; } + + public Guid MessageId { get; set; } + public string ServerId { get; set; } + /// /// Gets or sets the data. /// /// The data. public T Data { get; set; } } - } From 5ca68f9623e414b85ddbda1f97895f1b90bd05e0 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 26 Dec 2019 20:57:46 +0100 Subject: [PATCH 002/517] Fix nullref exception and added logging --- .../HttpServer/HttpListenerHost.cs | 17 +++-- .../HttpServer/WebSocketConnection.cs | 63 +++++++------------ .../Session/SessionManager.cs | 3 +- .../Session/SessionWebSocketListener.cs | 2 +- .../Session/WebSocketController.cs | 5 +- .../Net/IWebSocketConnection.cs | 16 ++--- 6 files changed, 41 insertions(+), 65 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 4baf96ab51..ebae4d0b1e 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -518,30 +518,29 @@ namespace Emby.Server.Implementations.HttpServer return; } - var url = context.Request.GetDisplayUrl(); - _logger.LogInformation("WS {Url}. UserAgent: {UserAgent}", url, context.Request.Headers[HeaderNames.UserAgent].ToString()); - try { - var webSocket = await context.WebSockets.AcceptWebSocketAsync(null).ConfigureAwait(false); + _logger.LogInformation("WS Request from {IP}", context.Connection.RemoteIpAddress); + + WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false); var connection = new WebSocketConnection( _loggerFactory.CreateLogger(), webSocket, - context.Connection.RemoteIpAddress) + context.Connection.RemoteIpAddress, + context.Request.Query) { - Url = url, - QueryString = context.Request.Query, OnReceive = ProcessWebSocketMessageReceived }; WebSocketConnected?.Invoke(this, new GenericEventArgs(connection)); await connection.ProcessAsync().ConfigureAwait(false); + _logger.LogInformation("WS closed from {IP}", context.Connection.RemoteIpAddress); } - catch (WebSocketException ex) + catch (Exception ex) // Otherwise ASP.Net will ignore the exception { - _logger.LogError(ex, "ProcessWebSocketRequest error"); + _logger.LogError(ex, "WebSocketRequestHandler error"); if (!context.Response.HasStarted) { context.Response.StatusCode = 500; diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index b4f420e5d2..88974f9aba 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -1,4 +1,6 @@ -using System; +#nullable enable + +using System; using System.Buffers; using System.IO.Pipelines; using System.Net; @@ -39,47 +41,38 @@ namespace Emby.Server.Implementations.HttpServer /// /// Initializes a new instance of the class. /// + /// The logger. /// The socket. /// The remote end point. - /// The logger. - /// socket - public WebSocketConnection(ILogger logger, WebSocket socket, IPAddress remoteEndPoint) + /// The query. + public WebSocketConnection( + ILogger logger, + WebSocket socket, + IPAddress? remoteEndPoint, + IQueryCollection query) { - if (socket == null) - { - throw new ArgumentNullException(nameof(socket)); - } - - if (remoteEndPoint != null) - { - throw new ArgumentNullException(nameof(remoteEndPoint)); - } - - if (logger == null) - { - throw new ArgumentNullException(nameof(logger)); - } - + _logger = logger; _socket = socket; RemoteEndPoint = remoteEndPoint; - _logger = logger; + QueryString = query; _jsonOptions = JsonDefaults.GetOptions(); + LastActivityDate = DateTime.Now; } /// - public event EventHandler Closed; + public event EventHandler? Closed; /// /// Gets or sets the remote end point. /// - public IPAddress RemoteEndPoint { get; private set; } + public IPAddress? RemoteEndPoint { get; } /// /// Gets or sets the receive action. /// /// The receive action. - public Func OnReceive { get; set; } + public Func? OnReceive { get; set; } /// /// Gets the last activity date. @@ -87,17 +80,11 @@ namespace Emby.Server.Implementations.HttpServer /// The last activity date. public DateTime LastActivityDate { get; private set; } - /// - /// Gets or sets the URL. - /// - /// The URL. - public string Url { get; set; } - /// /// Gets or sets the query string. /// /// The query string. - public IQueryCollection QueryString { get; set; } + public IQueryCollection QueryString { get; } /// /// Gets the state. @@ -115,11 +102,6 @@ namespace Emby.Server.Implementations.HttpServer /// message public Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken) { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions); return _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken); } @@ -140,7 +122,7 @@ namespace Emby.Server.Implementations.HttpServer int bytesRead = receiveresult.Count; if (bytesRead == 0) { - continue; + break; } // Tell the PipeWriter how much was read from the Socket @@ -154,6 +136,8 @@ namespace Emby.Server.Implementations.HttpServer break; } + LastActivityDate = DateTime.UtcNow; + if (receiveresult.EndOfMessage) { await ProcessInternal(pipe.Reader).ConfigureAwait(false); @@ -162,10 +146,7 @@ namespace Emby.Server.Implementations.HttpServer if (_socket.State == WebSocketState.Open) { - await _socket.CloseAsync( - WebSocketCloseStatus.NormalClosure, - string.Empty, // REVIEW: human readable explanation as to why the connection is closed. - cancellationToken).ConfigureAwait(false); + _logger.LogWarning("Stopped reading from websocket before it was closed"); } Closed?.Invoke(this, EventArgs.Empty); @@ -175,8 +156,6 @@ namespace Emby.Server.Implementations.HttpServer private async Task ProcessInternal(PipeReader reader) { - LastActivityDate = DateTime.UtcNow; - if (OnReceive == null) { return; diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index db00ceeb71..0d5df1dadc 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1726,6 +1726,7 @@ namespace Emby.Server.Implementations.Session string.Equals(i.Client, client)); } + /// public SessionInfo GetSessionByAuthenticationToken(AuthenticationInfo info, string deviceId, string remoteEndpoint, string appVersion) { if (info == null) @@ -1733,7 +1734,7 @@ namespace Emby.Server.Implementations.Session throw new ArgumentNullException(nameof(info)); } - var user = info.UserId.Equals(Guid.Empty) + var user = info.UserId == Guid.Empty ? null : _userManager.GetUserById(info.UserId); diff --git a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs index 13b42698d3..d4e4ba1f2f 100644 --- a/Emby.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/Emby.Server.Implementations/Session/SessionWebSocketListener.cs @@ -56,7 +56,7 @@ namespace Emby.Server.Implementations.Session } else { - _logger.LogWarning("Unable to determine session based on url: {0}", e.Argument.Url); + _logger.LogWarning("Unable to determine session based on query string: {0}", e.Argument.QueryString); } } diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index c17e67da93..536013c7ad 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -53,11 +53,12 @@ namespace Emby.Server.Implementations.Session private void OnConnectionClosed(object sender, EventArgs e) { - _logger.LogDebug("Removing websocket from session {Session}", _session.Id); var connection = (IWebSocketConnection)sender; + _logger.LogDebug("Removing websocket from session {Session}", _session.Id); _sockets.Remove(connection); - _sessionManager.CloseIfNeeded(_session); + connection.Closed -= OnConnectionClosed; connection.Dispose(); + _sessionManager.CloseIfNeeded(_session); } /// diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index e2a714d5b1..d5555884df 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Net; using System.Net.WebSockets; @@ -13,7 +15,7 @@ namespace MediaBrowser.Controller.Net /// /// Occurs when [closed]. /// - event EventHandler Closed; + event EventHandler? Closed; /// /// Gets the last activity date. @@ -21,23 +23,17 @@ namespace MediaBrowser.Controller.Net /// The last activity date. DateTime LastActivityDate { get; } - /// - /// Gets or sets the URL. - /// - /// The URL. - string Url { get; set; } - /// /// Gets or sets the query string. /// /// The query string. - IQueryCollection QueryString { get; set; } + IQueryCollection QueryString { get; } /// /// Gets or sets the receive action. /// /// The receive action. - Func OnReceive { get; set; } + Func? OnReceive { get; set; } /// /// Gets the state. @@ -49,7 +45,7 @@ namespace MediaBrowser.Controller.Net /// Gets the remote end point. /// /// The remote end point. - IPAddress RemoteEndPoint { get; } + IPAddress? RemoteEndPoint { get; } /// /// Sends a message asynchronously. From 4d311870d2f40f67da6df5641b53df637fdee88d Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 27 Dec 2019 14:42:53 +0100 Subject: [PATCH 003/517] Fix websocket handling --- .../HttpServer/WebSocketConnection.cs | 73 ++++++++----------- .../Session/WebSocketController.cs | 2 - .../Net/IWebSocketConnection.cs | 2 +- 3 files changed, 30 insertions(+), 47 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 88974f9aba..913a51217f 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -99,7 +99,6 @@ namespace Emby.Server.Implementations.HttpServer /// The message. /// The cancellation token. /// Task. - /// message public Task SendAsync(WebSocketMessage message, CancellationToken cancellationToken) { var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions); @@ -117,7 +116,6 @@ namespace Emby.Server.Implementations.HttpServer { // Allocate at least 512 bytes from the PipeWriter Memory memory = writer.GetMemory(512); - receiveresult = await _socket.ReceiveAsync(memory, cancellationToken); int bytesRead = receiveresult.Count; if (bytesRead == 0) @@ -144,33 +142,30 @@ namespace Emby.Server.Implementations.HttpServer } } while (_socket.State == WebSocketState.Open && receiveresult.MessageType != WebSocketMessageType.Close); - if (_socket.State == WebSocketState.Open) - { - _logger.LogWarning("Stopped reading from websocket before it was closed"); - } - Closed?.Invoke(this, EventArgs.Empty); - _socket.Dispose(); + await _socket.CloseAsync( + WebSocketCloseStatus.NormalClosure, + string.Empty, + cancellationToken).ConfigureAwait(false); } private async Task ProcessInternal(PipeReader reader) { + ReadResult result = await reader.ReadAsync().ConfigureAwait(false); + ReadOnlySequence buffer = result.Buffer; + if (OnReceive == null) { + // Tell the PipeReader how much of the buffer we have consumed + reader.AdvanceTo(buffer.End); return; } + WebSocketMessage stub; try { - var result = await reader.ReadAsync().ConfigureAwait(false); - if (!result.IsCompleted) - { - return; - } - WebSocketMessage stub; - var buffer = result.Buffer; if (buffer.IsSingleSegment) { stub = JsonSerializer.Deserialize>(buffer.FirstSpan, _jsonOptions); @@ -188,46 +183,36 @@ namespace Emby.Server.Implementations.HttpServer ArrayPool.Shared.Return(buf); } } - - var info = new WebSocketMessageInfo - { - MessageType = stub.MessageType, - Data = stub.Data.ToString(), - Connection = this - }; - - await OnReceive(info).ConfigureAwait(false); } catch (JsonException ex) { + // Tell the PipeReader how much of the buffer we have consumed + reader.AdvanceTo(buffer.End); _logger.LogError(ex, "Error processing web socket message"); + return; } - } - /// - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } + // Tell the PipeReader how much of the buffer we have consumed + reader.AdvanceTo(buffer.End); - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (_disposed) + _logger.LogDebug("WS received message: {@Message}", stub); + + var info = new WebSocketMessageInfo { - return; - } + MessageType = stub.MessageType, + Data = stub.Data?.ToString(), // Data can be null + Connection = this + }; + + _logger.LogDebug("WS message info: {@MessageInfo}", info); - if (dispose) + await OnReceive(info).ConfigureAwait(false); + + // Stop reading if there's no more data coming + if (result.IsCompleted) { - _socket.Dispose(); + return; } - - _disposed = true; } } } diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index 536013c7ad..c3c4b716fc 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -57,7 +57,6 @@ namespace Emby.Server.Implementations.Session _logger.LogDebug("Removing websocket from session {Session}", _session.Id); _sockets.Remove(connection); connection.Closed -= OnConnectionClosed; - connection.Dispose(); _sessionManager.CloseIfNeeded(_session); } @@ -96,7 +95,6 @@ namespace Emby.Server.Implementations.Session foreach (var socket in _sockets) { socket.Closed -= OnConnectionClosed; - socket.Dispose(); } _disposed = true; diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index d5555884df..09e43c683f 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net { - public interface IWebSocketConnection : IDisposable + public interface IWebSocketConnection { /// /// Occurs when [closed]. From 8865b3ea3d0af201c37aa129016b843f0b9fe686 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 27 Dec 2019 15:20:27 +0100 Subject: [PATCH 004/517] Remove dead code and improve logging --- .../HttpServer/HttpListenerHost.cs | 8 +- .../HttpServer/WebSocketConnection.cs | 4 +- .../Middleware/WebSocketMiddleware.cs | 39 ------- .../WebSockets/WebSocketHandler.cs | 10 -- .../WebSockets/WebSocketManager.cs | 104 ------------------ .../System/ActivityLogWebSocketListener.cs | 17 ++- .../Net/BasePeriodicWebSocketListener.cs | 11 +- 7 files changed, 18 insertions(+), 175 deletions(-) delete mode 100644 Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs delete mode 100644 Emby.Server.Implementations/WebSockets/WebSocketHandler.cs delete mode 100644 Emby.Server.Implementations/WebSockets/WebSocketManager.cs diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index ebae4d0b1e..3cdb0ecaeb 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -520,7 +520,7 @@ namespace Emby.Server.Implementations.HttpServer try { - _logger.LogInformation("WS Request from {IP}", context.Connection.RemoteIpAddress); + _logger.LogInformation("WS {IP} request", context.Connection.RemoteIpAddress); WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false); @@ -536,11 +536,11 @@ namespace Emby.Server.Implementations.HttpServer WebSocketConnected?.Invoke(this, new GenericEventArgs(connection)); await connection.ProcessAsync().ConfigureAwait(false); - _logger.LogInformation("WS closed from {IP}", context.Connection.RemoteIpAddress); + _logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress); } catch (Exception ex) // Otherwise ASP.Net will ignore the exception { - _logger.LogError(ex, "WebSocketRequestHandler error"); + _logger.LogError(ex, "WS {IP} WebSocketRequestHandler error"); if (!context.Response.HasStarted) { context.Response.StatusCode = 500; @@ -705,8 +705,6 @@ namespace Emby.Server.Implementations.HttpServer return Task.CompletedTask; } - _logger.LogDebug("Websocket message received: {0}", result.MessageType); - IEnumerable GetTasks() { foreach (var x in _webSocketListeners) diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 913a51217f..0afd0ecce1 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -195,7 +195,7 @@ namespace Emby.Server.Implementations.HttpServer // Tell the PipeReader how much of the buffer we have consumed reader.AdvanceTo(buffer.End); - _logger.LogDebug("WS received message: {@Message}", stub); + _logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub); var info = new WebSocketMessageInfo { @@ -204,7 +204,7 @@ namespace Emby.Server.Implementations.HttpServer Connection = this }; - _logger.LogDebug("WS message info: {@MessageInfo}", info); + _logger.LogDebug("WS {IP} message info: {@MessageInfo}", RemoteEndPoint, info); await OnReceive(info).ConfigureAwait(false); diff --git a/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs b/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs deleted file mode 100644 index fda32da5e8..0000000000 --- a/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Logging; -using WebSocketManager = Emby.Server.Implementations.WebSockets.WebSocketManager; - -namespace Emby.Server.Implementations.Middleware -{ - public class WebSocketMiddleware - { - private readonly RequestDelegate _next; - private readonly ILogger _logger; - private readonly WebSocketManager _webSocketManager; - - public WebSocketMiddleware(RequestDelegate next, ILogger logger, WebSocketManager webSocketManager) - { - _next = next; - _logger = logger; - _webSocketManager = webSocketManager; - } - - public async Task Invoke(HttpContext httpContext) - { - _logger.LogInformation("Handling request: " + httpContext.Request.Path); - - if (httpContext.WebSockets.IsWebSocketRequest) - { - var webSocketContext = await httpContext.WebSockets.AcceptWebSocketAsync(null).ConfigureAwait(false); - if (webSocketContext != null) - { - await _webSocketManager.OnWebSocketConnected(webSocketContext).ConfigureAwait(false); - } - } - else - { - await _next.Invoke(httpContext).ConfigureAwait(false); - } - } - } -} diff --git a/Emby.Server.Implementations/WebSockets/WebSocketHandler.cs b/Emby.Server.Implementations/WebSockets/WebSocketHandler.cs deleted file mode 100644 index eb18774408..0000000000 --- a/Emby.Server.Implementations/WebSockets/WebSocketHandler.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Threading.Tasks; -using MediaBrowser.Model.Net; - -namespace Emby.Server.Implementations.WebSockets -{ - public interface IWebSocketHandler - { - Task ProcessMessage(WebSocketMessage message, TaskCompletionSource taskCompletionSource); - } -} diff --git a/Emby.Server.Implementations/WebSockets/WebSocketManager.cs b/Emby.Server.Implementations/WebSockets/WebSocketManager.cs deleted file mode 100644 index efd97e4ff1..0000000000 --- a/Emby.Server.Implementations/WebSockets/WebSocketManager.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Net.WebSockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller.Net; -using MediaBrowser.Model.Net; -using MediaBrowser.Model.Serialization; -using Microsoft.Extensions.Logging; -using UtfUnknown; - -namespace Emby.Server.Implementations.WebSockets -{ - public class WebSocketManager - { - private readonly IWebSocketHandler[] _webSocketHandlers; - private readonly IJsonSerializer _jsonSerializer; - private readonly ILogger _logger; - private const int BufferSize = 4096; - - public WebSocketManager(IWebSocketHandler[] webSocketHandlers, IJsonSerializer jsonSerializer, ILogger logger) - { - _webSocketHandlers = webSocketHandlers; - _jsonSerializer = jsonSerializer; - _logger = logger; - } - - public async Task OnWebSocketConnected(WebSocket webSocket) - { - var taskCompletionSource = new TaskCompletionSource(); - var cancellationToken = new CancellationTokenSource().Token; - WebSocketReceiveResult result; - var message = new List(); - - // Keep listening for incoming messages, otherwise the socket closes automatically - do - { - var buffer = WebSocket.CreateServerBuffer(BufferSize); - result = await webSocket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false); - message.AddRange(buffer.Array.Take(result.Count)); - - if (result.EndOfMessage) - { - await ProcessMessage(message.ToArray(), taskCompletionSource).ConfigureAwait(false); - message.Clear(); - } - } while (!taskCompletionSource.Task.IsCompleted && - webSocket.State == WebSocketState.Open && - result.MessageType != WebSocketMessageType.Close); - - if (webSocket.State == WebSocketState.Open) - { - await webSocket.CloseAsync( - result.CloseStatus ?? WebSocketCloseStatus.NormalClosure, - result.CloseStatusDescription, - cancellationToken).ConfigureAwait(false); - } - } - - private async Task ProcessMessage(byte[] messageBytes, TaskCompletionSource taskCompletionSource) - { - var charset = CharsetDetector.DetectFromBytes(messageBytes).Detected?.EncodingName; - var message = string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase) - ? Encoding.UTF8.GetString(messageBytes, 0, messageBytes.Length) - : Encoding.ASCII.GetString(messageBytes, 0, messageBytes.Length); - - // All messages are expected to be valid JSON objects - if (!message.StartsWith("{", StringComparison.OrdinalIgnoreCase)) - { - _logger.LogDebug("Received web socket message that is not a json structure: {Message}", message); - return; - } - - try - { - var info = _jsonSerializer.DeserializeFromString>(message); - - _logger.LogDebug("Websocket message received: {0}", info.MessageType); - - var tasks = _webSocketHandlers.Select(handler => Task.Run(() => - { - try - { - handler.ProcessMessage(info, taskCompletionSource).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "{HandlerType} failed processing WebSocket message {MessageType}", - handler.GetType().Name, info.MessageType ?? string.Empty); - } - })); - - await Task.WhenAll(tasks); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error processing web socket message"); - } - } - } -} diff --git a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs index a036619b81..60b190a0e7 100644 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Threading; +using System; using System.Threading.Tasks; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Activity; @@ -11,7 +10,7 @@ namespace MediaBrowser.Api.System /// /// Class SessionInfoWebSocketListener /// - public class ActivityLogWebSocketListener : BasePeriodicWebSocketListener, WebSocketListenerState> + public class ActivityLogWebSocketListener : BasePeriodicWebSocketListener { /// /// Gets the name. @@ -27,10 +26,10 @@ namespace MediaBrowser.Api.System public ActivityLogWebSocketListener(ILogger logger, IActivityManager activityManager) : base(logger) { _activityManager = activityManager; - _activityManager.EntryCreated += _activityManager_EntryCreated; + _activityManager.EntryCreated += OnEntryCreated; } - void _activityManager_EntryCreated(object sender, GenericEventArgs e) + private void OnEntryCreated(object sender, GenericEventArgs e) { SendData(true); } @@ -39,15 +38,15 @@ namespace MediaBrowser.Api.System /// Gets the data to send. /// /// Task{SystemInfo}. - protected override Task> GetDataToSend() + protected override Task GetDataToSend() { - return Task.FromResult(new List()); + return Task.FromResult(Array.Empty()); } - + /// protected override void Dispose(bool dispose) { - _activityManager.EntryCreated -= _activityManager_EntryCreated; + _activityManager.EntryCreated -= OnEntryCreated; base.Dispose(dispose); } diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index 9d71426d88..b193cbb55a 100644 --- a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs +++ b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs @@ -77,8 +77,6 @@ namespace MediaBrowser.Controller.Net return Task.CompletedTask; } - protected readonly CultureInfo UsCulture = new CultureInfo("en-US"); - /// /// Starts sending messages over a web socket /// @@ -87,12 +85,12 @@ namespace MediaBrowser.Controller.Net { var vals = message.Data.Split(','); - var dueTimeMs = long.Parse(vals[0], UsCulture); - var periodMs = long.Parse(vals[1], UsCulture); + var dueTimeMs = long.Parse(vals[0], CultureInfo.InvariantCulture); + var periodMs = long.Parse(vals[1], CultureInfo.InvariantCulture); var cancellationTokenSource = new CancellationTokenSource(); - Logger.LogDebug("{1} Begin transmitting over websocket to {0}", message.Connection.RemoteEndPoint, GetType().Name); + Logger.LogDebug("WS {1} begin transmitting to {0}", message.Connection.RemoteEndPoint, GetType().Name); var state = new TStateType { @@ -196,7 +194,7 @@ namespace MediaBrowser.Controller.Net /// The connection. private void DisposeConnection(Tuple connection) { - Logger.LogDebug("{1} stop transmitting over websocket to {0}", connection.Item1.RemoteEndPoint, GetType().Name); + Logger.LogDebug("WS {1} stop transmitting to {0}", connection.Item1.RemoteEndPoint, GetType().Name); // TODO disposing the connection seems to break websockets in subtle ways, so what is the purpose of this function really... // connection.Item1.Dispose(); @@ -241,6 +239,7 @@ namespace MediaBrowser.Controller.Net public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } } From bdd823d22ff4d20e8aa2e5d8bf34e0faaad285ba Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 27 Dec 2019 15:42:59 +0100 Subject: [PATCH 005/517] Handle unexpected disconnect --- .../HttpServer/HttpListenerHost.cs | 2 +- .../HttpServer/WebSocketConnection.cs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 3cdb0ecaeb..05dbad624b 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -540,7 +540,7 @@ namespace Emby.Server.Implementations.HttpServer } catch (Exception ex) // Otherwise ASP.Net will ignore the exception { - _logger.LogError(ex, "WS {IP} WebSocketRequestHandler error"); + _logger.LogError(ex, "WS {IP} WebSocketRequestHandler error", context.Connection.RemoteIpAddress); if (!context.Response.HasStarted) { context.Response.StatusCode = 500; diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 0afd0ecce1..7c0d82d899 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -116,7 +116,16 @@ namespace Emby.Server.Implementations.HttpServer { // Allocate at least 512 bytes from the PipeWriter Memory memory = writer.GetMemory(512); - receiveresult = await _socket.ReceiveAsync(memory, cancellationToken); + try + { + receiveresult = await _socket.ReceiveAsync(memory, cancellationToken); + } + catch (WebSocketException ex) + { + _logger.LogWarning("WS {IP} error receiving data: {Message}", RemoteEndPoint, ex.Message); + break; + } + int bytesRead = receiveresult.Count; if (bytesRead == 0) { From f89e18ea26aa2f4eec19f52ee6dfd28b53cee5df Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Fri, 27 Dec 2019 15:56:20 +0100 Subject: [PATCH 006/517] Improve error handling --- .../HttpServer/WebSocketConnection.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 7c0d82d899..0b376bf3c2 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -149,14 +149,21 @@ namespace Emby.Server.Implementations.HttpServer { await ProcessInternal(pipe.Reader).ConfigureAwait(false); } - } while (_socket.State == WebSocketState.Open && receiveresult.MessageType != WebSocketMessageType.Close); + } while ( + (_socket.State == WebSocketState.Open || _socket.State == WebSocketState.Connecting) + && receiveresult.MessageType != WebSocketMessageType.Close); Closed?.Invoke(this, EventArgs.Empty); - await _socket.CloseAsync( - WebSocketCloseStatus.NormalClosure, - string.Empty, - cancellationToken).ConfigureAwait(false); + if (_socket.State == WebSocketState.Open + || _socket.State == WebSocketState.CloseReceived + || _socket.State == WebSocketState.CloseSent) + { + await _socket.CloseAsync( + WebSocketCloseStatus.NormalClosure, + string.Empty, + cancellationToken).ConfigureAwait(false); + } } private async Task ProcessInternal(PipeReader reader) From d01ba49be3cd643b7b306216cb96aef31dba9569 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sun, 29 Dec 2019 14:53:04 +0100 Subject: [PATCH 007/517] Fix space --- Emby.Server.Implementations/HttpServer/WebSocketConnection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 0b376bf3c2..a8d5e9086a 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -211,7 +211,7 @@ namespace Emby.Server.Implementations.HttpServer // Tell the PipeReader how much of the buffer we have consumed reader.AdvanceTo(buffer.End); - _logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub); + _logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub); var info = new WebSocketMessageInfo { From ee964f8a58a0324b9e7b2ae37a9d4831f59c922f Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sun, 29 Dec 2019 15:44:17 +0100 Subject: [PATCH 008/517] Don't log message info --- Emby.Server.Implementations/HttpServer/WebSocketConnection.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index a8d5e9086a..1af748ebc2 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -220,8 +220,6 @@ namespace Emby.Server.Implementations.HttpServer Connection = this }; - _logger.LogDebug("WS {IP} message info: {@MessageInfo}", RemoteEndPoint, info); - await OnReceive(info).ConfigureAwait(false); // Stop reading if there's no more data coming From 407f54e7764a6bfd8e4ccc0df897fac7e8c658b4 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Mon, 13 Jan 2020 20:03:49 +0100 Subject: [PATCH 009/517] Style fixes --- .../Session/WebSocketController.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/Session/WebSocketController.cs b/Emby.Server.Implementations/Session/WebSocketController.cs index c3c4b716fc..c7ef9b1cec 100644 --- a/Emby.Server.Implementations/Session/WebSocketController.cs +++ b/Emby.Server.Implementations/Session/WebSocketController.cs @@ -1,3 +1,7 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 +#nullable enable + using System; using System.Collections.Generic; using System.Linq; @@ -42,7 +46,6 @@ namespace Emby.Server.Implementations.Session private IEnumerable GetActiveSockets() => _sockets.Where(i => i.State == WebSocketState.Open); - /// public void AddWebSocket(IWebSocketConnection connection) { _logger.LogDebug("Adding websocket to session {Session}", _session.Id); @@ -76,12 +79,14 @@ namespace Emby.Server.Implementations.Session return Task.CompletedTask; } - return socket.SendAsync(new WebSocketMessage - { - Data = data, - MessageType = name, - MessageId = messageId - }, cancellationToken); + return socket.SendAsync( + new WebSocketMessage + { + Data = data, + MessageType = name, + MessageId = messageId + }, + cancellationToken); } /// From 5d760b7ee806d3fb00ac5aa7d0981362526f1d11 Mon Sep 17 00:00:00 2001 From: Davide Polonio Date: Sun, 1 Mar 2020 21:38:34 +0100 Subject: [PATCH 010/517] Fix emby/user/public API leaking private data This commit fixes the emby/user/public API that was returning more data than necessary. Now only the following information are returned: - the account name - the primary image tag - the field hasPassword - the field hasConfiguredPassword, useful for the first wizard only (see https://github.com/jellyfin/jellyfin/issues/880#issuecomment-465370051) - the primary image aspect ratio A new DTO class, PrivateUserDTO has been created, and the route has been modified in order to return that data object. --- .../Library/UserManager.cs | 25 ++++++++++ MediaBrowser.Api/UserService.cs | 36 +++++++++----- .../Library/IUserManager.cs | 8 ++++ MediaBrowser.Model/Dto/PublicUserDto.cs | 48 +++++++++++++++++++ 4 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 MediaBrowser.Model/Dto/PublicUserDto.cs diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 6e203f894f..8941767b41 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -613,6 +613,31 @@ namespace Emby.Server.Implementations.Library return dto; } + public PublicUserDto GetPublicUserDto(User user, string remoteEndPoint = null) + { + if (user == null) + { + throw new ArgumentNullException(nameof(user)); + } + + bool hasConfiguredPassword = GetAuthenticationProvider(user).HasPassword(user); + bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(GetAuthenticationProvider(user).GetEasyPasswordHash(user)); + + bool hasPassword = user.Configuration.EnableLocalPassword && + !string.IsNullOrEmpty(remoteEndPoint) && + _networkManager.IsInLocalNetwork(remoteEndPoint) ? hasConfiguredEasyPassword : hasConfiguredPassword; + + + PublicUserDto dto = new PublicUserDto + { + Name = user.Name, + HasPassword = hasPassword, + HasConfiguredPassword = hasConfiguredPassword, + }; + + return dto; + } + public UserDto GetOfflineUserDto(User user) { var dto = GetUserDto(user); diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 4015143497..b4ab8c9740 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.Api } [Route("/Users/Public", "GET", Summary = "Gets a list of publicly visible users for display on a login screen.")] - public class GetPublicUsers : IReturn + public class GetPublicUsers : IReturn { } @@ -266,22 +266,36 @@ namespace MediaBrowser.Api _authContext = authContext; } + /// + /// Gets the public available Users information + /// + /// The request. + /// System.Object. public object Get(GetPublicUsers request) { - // If the startup wizard hasn't been completed then just return all users - if (!ServerConfigurationManager.Configuration.IsStartupWizardCompleted) + var users = _userManager + .Users + .Where(item => item.Policy.IsDisabled == false) + .Where(item => item.Policy.IsHidden == false); + + var deviceId = _authContext.GetAuthorizationInfo(Request).DeviceId; + + if (!string.IsNullOrWhiteSpace(deviceId)) { - return Get(new GetUsers - { - IsDisabled = false - }); + users = users.Where(i => _deviceManager.CanAccessDevice(i, deviceId)); } - return Get(new GetUsers + if (!_networkManager.IsInLocalNetwork(Request.RemoteIp)) { - IsHidden = false, - IsDisabled = false - }, true, true); + users = users.Where(i => i.Policy.EnableRemoteAccess); + } + + var result = users + .OrderBy(u => u.Name) + .Select(i => _userManager.GetPublicUserDto(i, Request.RemoteIp)) + .ToArray(); + + return ToOptimizedResult(result); } /// diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index be7b4ce59d..ec6cb35eb9 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -143,6 +143,14 @@ namespace MediaBrowser.Controller.Library /// UserDto. UserDto GetUserDto(User user, string remoteEndPoint = null); + /// + /// Gets the user public dto. + /// + /// Ther user.\ + /// The remote end point. + /// A public UserDto, aka a UserDto stripped of personal data. + PublicUserDto GetPublicUserDto(User user, string remoteEndPoint = null); + /// /// Authenticates the user. /// diff --git a/MediaBrowser.Model/Dto/PublicUserDto.cs b/MediaBrowser.Model/Dto/PublicUserDto.cs new file mode 100644 index 0000000000..bf529a2d0b --- /dev/null +++ b/MediaBrowser.Model/Dto/PublicUserDto.cs @@ -0,0 +1,48 @@ +using System; +using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Users; + +namespace MediaBrowser.Model.Dto +{ + /// + /// Class PublicUserDto. Its goal is to show only public information about a user + /// + public class PublicUserDto : IItemDto + { + /// + /// Gets or sets the name. + /// + /// The name. + public string Name { get; set; } + + /// + /// Gets or sets the primary image tag. + /// + /// The primary image tag. + public string PrimaryImageTag { get; set; } + + /// + /// Gets or sets a value indicating whether this instance has password. + /// + /// true if this instance has password; otherwise, false. + public bool HasPassword { get; set; } + + /// + /// Gets or sets a value indicating whether this instance has configured password. + /// + /// true if this instance has configured password; otherwise, false. + public bool HasConfiguredPassword { get; set; } + + /// + /// Gets or sets the primary image aspect ratio. + /// + /// The primary image aspect ratio. + public double? PrimaryImageAspectRatio { get; set; } + + /// + public override string ToString() + { + return Name ?? base.ToString(); + } + } +} \ No newline at end of file From 737d4d2b3f200e2dc140151d11dc9f29d70bd5bf Mon Sep 17 00:00:00 2001 From: Davide Polonio Date: Tue, 3 Mar 2020 19:51:03 +0100 Subject: [PATCH 011/517] Fix conditional with a less verbose one Co-Authored-By: Vasily --- MediaBrowser.Api/UserService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index b4ab8c9740..5ad4fce64d 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -275,8 +275,8 @@ namespace MediaBrowser.Api { var users = _userManager .Users - .Where(item => item.Policy.IsDisabled == false) - .Where(item => item.Policy.IsHidden == false); + .Where(item => !item.Policy.IsDisabled) + .Where(item => !item.Policy.IsHidden); var deviceId = _authContext.GetAuthorizationInfo(Request).DeviceId; From cd471ed4df9260d9de3cfa1e58abf537aa460727 Mon Sep 17 00:00:00 2001 From: Davide Polonio Date: Tue, 3 Mar 2020 20:20:35 +0100 Subject: [PATCH 012/517] Fix emby/users/public not taking into account first run The previous implementation was not taking in account the first seup phase. Now the check has been added. A little method refactor has been done in order to make the code more elegant. --- MediaBrowser.Api/UserService.cs | 36 +++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 5ad4fce64d..bb630c0b37 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -273,29 +273,31 @@ namespace MediaBrowser.Api /// System.Object. public object Get(GetPublicUsers request) { - var users = _userManager + var result = _userManager .Users - .Where(item => !item.Policy.IsDisabled) - .Where(item => !item.Policy.IsHidden); + .Where(item => !item.Policy.IsDisabled); - var deviceId = _authContext.GetAuthorizationInfo(Request).DeviceId; - - if (!string.IsNullOrWhiteSpace(deviceId)) + if (ServerConfigurationManager.Configuration.IsStartupWizardCompleted) { - users = users.Where(i => _deviceManager.CanAccessDevice(i, deviceId)); - } + var deviceId = _authContext.GetAuthorizationInfo(Request).DeviceId; + result = result.Where(item => !item.Policy.IsHidden); - if (!_networkManager.IsInLocalNetwork(Request.RemoteIp)) - { - users = users.Where(i => i.Policy.EnableRemoteAccess); - } + if (!string.IsNullOrWhiteSpace(deviceId)) + { + result = result.Where(i => _deviceManager.CanAccessDevice(i, deviceId)); + } - var result = users - .OrderBy(u => u.Name) - .Select(i => _userManager.GetPublicUserDto(i, Request.RemoteIp)) - .ToArray(); + if (!_networkManager.IsInLocalNetwork(Request.RemoteIp)) + { + result = result.Where(i => i.Policy.EnableRemoteAccess); + } + } - return ToOptimizedResult(result); + return ToOptimizedResult(result + .OrderBy(u => u.Name) + .Select(i => _userManager.GetPublicUserDto(i, Request.RemoteIp)) + .ToArray() + ); } /// From 5099f6e4a24128e47edbad674f551c5ebe29cb7e Mon Sep 17 00:00:00 2001 From: Davide Polonio Date: Thu, 5 Mar 2020 08:01:47 +0100 Subject: [PATCH 013/517] Add FIXME in HasConfiguredPassword public user DTO method --- MediaBrowser.Model/Dto/PublicUserDto.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Model/Dto/PublicUserDto.cs b/MediaBrowser.Model/Dto/PublicUserDto.cs index bf529a2d0b..d5fd431eb6 100644 --- a/MediaBrowser.Model/Dto/PublicUserDto.cs +++ b/MediaBrowser.Model/Dto/PublicUserDto.cs @@ -31,6 +31,7 @@ namespace MediaBrowser.Model.Dto /// Gets or sets a value indicating whether this instance has configured password. /// /// true if this instance has configured password; otherwise, false. + // FIXME this shouldn't be here, but it's necessary when changing password at the first login public bool HasConfiguredPassword { get; set; } /// From 85da15685f7a761af3a34f1c591bf129aa5deb5f Mon Sep 17 00:00:00 2001 From: Andreas B <6439218+YouKnowBlom@users.noreply.github.com> Date: Sun, 15 Mar 2020 15:06:38 +0100 Subject: [PATCH 014/517] Refactor DynamicHlsService.AppendPlaylist to use StringBuilder --- MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 262f517869..8787eb2a3f 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -724,7 +724,10 @@ namespace MediaBrowser.Api.Playback.Hls private void AppendPlaylist(StringBuilder builder, StreamState state, string url, int bitrate, string subtitleGroup) { - var header = "#EXT-X-STREAM-INF:BANDWIDTH=" + bitrate.ToString(CultureInfo.InvariantCulture) + ",AVERAGE-BANDWIDTH=" + bitrate.ToString(CultureInfo.InvariantCulture); + builder.Append("#EXT-X-STREAM-INF:BANDWIDTH=") + .Append(bitrate.ToString(CultureInfo.InvariantCulture)) + .Append(",AVERAGE-BANDWIDTH=") + .Append(bitrate.ToString(CultureInfo.InvariantCulture)); // tvos wants resolution, codecs, framerate //if (state.TargetFramerate.HasValue) @@ -734,10 +737,12 @@ namespace MediaBrowser.Api.Playback.Hls if (!string.IsNullOrWhiteSpace(subtitleGroup)) { - header += string.Format(",SUBTITLES=\"{0}\"", subtitleGroup); + builder.Append(",SUBTITLES=\"") + .Append(subtitleGroup) + .Append('"'); } - builder.AppendLine(header); + builder.Append(Environment.NewLine); builder.AppendLine(url); } From f2858878d166df214aee20f2dc0710b766285c91 Mon Sep 17 00:00:00 2001 From: Andreas B <6439218+YouKnowBlom@users.noreply.github.com> Date: Wed, 11 Mar 2020 18:14:36 +0100 Subject: [PATCH 015/517] Add CODECS field to HLS master playlist --- .../Playback/Hls/DynamicHlsService.cs | 110 +++++++++++++++ .../Playback/Hls/HlsCodecStringFactory.cs | 126 ++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 MediaBrowser.Api/Playback/Hls/HlsCodecStringFactory.cs diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 8787eb2a3f..e6c9213912 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -722,6 +722,114 @@ namespace MediaBrowser.Api.Playback.Hls //return state.VideoRequest.VideoBitRate.HasValue; } + /// + /// Gets a formatted string of the output audio codec, for use in the CODECS field. + /// + /// + /// + /// StreamState of the current stream. + /// Formatted audio codec string. + private string GetPlaylistAudioCodecs(StreamState state) + { + + if (string.Equals(state.ActualOutputAudioCodec, "aac", StringComparison.OrdinalIgnoreCase)) + { + string profile = state.GetRequestedProfiles("aac").FirstOrDefault(); + + return HlsCodecStringFactory.GetAACString(profile); + } + else if (string.Equals(state.ActualOutputAudioCodec, "mp3", StringComparison.OrdinalIgnoreCase)) + { + return HlsCodecStringFactory.GetMP3String(); + } + else if (string.Equals(state.ActualOutputAudioCodec, "ac3", StringComparison.OrdinalIgnoreCase)) + { + return HlsCodecStringFactory.GetAC3String(); + } + else if (string.Equals(state.ActualOutputAudioCodec, "eac3", StringComparison.OrdinalIgnoreCase)) + { + return HlsCodecStringFactory.GetEAC3String(); + } + + return string.Empty; + } + + /// + /// Gets a formatted string of the output video codec, for use in the CODECS field. + /// + /// + /// + /// StreamState of the current stream. + /// Formatted video codec string. + private string GetPlaylistVideoCodecs(StreamState state) + { + int level = Convert.ToInt32(state.GetRequestedLevel(state.ActualOutputVideoCodec)); + + if (string.Equals(state.ActualOutputVideoCodec, "h264", StringComparison.OrdinalIgnoreCase)) + { + string profile = state.GetRequestedProfiles("h264").FirstOrDefault(); + + return HlsCodecStringFactory.GetH264String(profile, level); + } + else if (string.Equals(state.ActualOutputVideoCodec, "h265", StringComparison.OrdinalIgnoreCase) + || string.Equals(state.ActualOutputVideoCodec, "hevc", StringComparison.OrdinalIgnoreCase)) + { + string profile = state.GetRequestedProfiles("h265").FirstOrDefault(); + + return HlsCodecStringFactory.GetH265String(profile, level); + } + + return string.Empty; + } + + /// + /// Appends a CODECS field containing formatted strings of + /// the active streams output video and audio codecs. + /// + /// + /// + /// + /// StringBuilder to append the field to. + /// StreamState of the current stream. + private void AppendPlaylistCodecsField(StringBuilder builder, StreamState state) + { + // Video + string videoCodecs = string.Empty; + if (!string.IsNullOrEmpty(state.ActualOutputVideoCodec)) + { + videoCodecs = GetPlaylistVideoCodecs(state); + } + + // Audio + string audioCodecs = string.Empty; + if (!string.IsNullOrEmpty(state.ActualOutputAudioCodec)) + { + audioCodecs = GetPlaylistAudioCodecs(state); + } + + if (!string.IsNullOrEmpty(videoCodecs) || !string.IsNullOrEmpty(audioCodecs)) + { + builder.Append(",CODECS=\""); + + if (!string.IsNullOrEmpty(videoCodecs) && !string.IsNullOrEmpty(audioCodecs)) + { + builder.Append(videoCodecs) + .Append(',') + .Append(audioCodecs); + } + else if (!string.IsNullOrEmpty(videoCodecs)) + { + builder.Append(videoCodecs); + } + else if (!string.IsNullOrEmpty(audioCodecs)) + { + builder.Append(audioCodecs); + } + + builder.Append('"'); + } + } + private void AppendPlaylist(StringBuilder builder, StreamState state, string url, int bitrate, string subtitleGroup) { builder.Append("#EXT-X-STREAM-INF:BANDWIDTH=") @@ -735,6 +843,8 @@ namespace MediaBrowser.Api.Playback.Hls // header += string.Format(",FRAME-RATE=\"{0}\"", state.TargetFramerate.Value.ToString(CultureInfo.InvariantCulture)); //} + AppendPlaylistCodecsField(builder, state); + if (!string.IsNullOrWhiteSpace(subtitleGroup)) { builder.Append(",SUBTITLES=\"") diff --git a/MediaBrowser.Api/Playback/Hls/HlsCodecStringFactory.cs b/MediaBrowser.Api/Playback/Hls/HlsCodecStringFactory.cs new file mode 100644 index 0000000000..3bbb77a65e --- /dev/null +++ b/MediaBrowser.Api/Playback/Hls/HlsCodecStringFactory.cs @@ -0,0 +1,126 @@ +using System; +using System.Text; + + +namespace MediaBrowser.Api.Playback +{ + /// + /// Get various codec strings for use in HLS playlists. + /// + static class HlsCodecStringFactory + { + + /// + /// Gets a MP3 codec string. + /// + /// MP3 codec string. + public static string GetMP3String() + { + return "mp4a.40.34"; + } + + /// + /// Gets an AAC codec string. + /// + /// AAC profile. + /// AAC codec string. + public static string GetAACString(string profile) + { + StringBuilder result = new StringBuilder("mp4a", 9); + + if (string.Equals(profile, "HE", StringComparison.OrdinalIgnoreCase)) + { + result.Append(".40.5"); + } + else + { + // Default to LC if profile is invalid + result.Append(".40.2"); + } + + return result.ToString(); + } + + /// + /// Gets a H.264 codec string. + /// + /// H.264 profile. + /// H.264 level. + /// H.264 string. + public static string GetH264String(string profile, int level) + { + StringBuilder result = new StringBuilder("avc1", 11); + + if (string.Equals(profile, "high", StringComparison.OrdinalIgnoreCase)) + { + result.Append(".6400"); + } + else if (string.Equals(profile, "main", StringComparison.OrdinalIgnoreCase)) + { + result.Append(".4D40"); + } + else if (string.Equals(profile, "baseline", StringComparison.OrdinalIgnoreCase)) + { + result.Append(".42E0"); + } + else + { + // Default to constrained baseline if profile is invalid + result.Append(".4240"); + } + + string levelHex = level.ToString("X2"); + result.Append(levelHex); + + return result.ToString(); + } + + /// + /// Gets a H.265 codec string. + /// + /// H.265 profile. + /// H.265 level. + /// H.265 string. + public static string GetH265String(string profile, int level) + { + // The h265 syntax is a bit of a mystery at the time this comment was written. + // This is what I've found through various sources: + // FORMAT: [codecTag].[profile].[constraint?].L[level * 30].[UNKNOWN] + StringBuilder result = new StringBuilder("hev1", 16); + + if (string.Equals(profile, "main10", StringComparison.OrdinalIgnoreCase)) + { + result.Append(".2.6"); + } + else + { + // Default to main if profile is invalid + result.Append(".1.6"); + } + + result.Append(".L") + .Append(level * 3) + .Append(".B0"); + + return result.ToString(); + } + + /// + /// Gets an AC-3 codec string. + /// + /// AC-3 codec string. + public static string GetAC3String() + { + return "mp4a.a5"; + } + + /// + /// Gets an E-AC-3 codec string. + /// + /// E-AC-3 codec string. + public static string GetEAC3String() + { + return "mp4a.a6"; + } + } +} From 8a990d1d95aa22840bae5c3494cb5371bcf2b4d8 Mon Sep 17 00:00:00 2001 From: Andreas B <6439218+YouKnowBlom@users.noreply.github.com> Date: Wed, 11 Mar 2020 18:16:57 +0100 Subject: [PATCH 016/517] Add FRAME-RATE field to HLS master playlist --- .../Playback/Hls/DynamicHlsService.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index e6c9213912..d56b5cbff4 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -830,6 +830,32 @@ namespace MediaBrowser.Api.Playback.Hls } } + /// + /// Appends a FRAME-RATE field containing the framerate of the output stream. + /// + /// + /// StringBuilder to append the field to. + /// StreamState of the current stream. + private void AppendPlaylistFramerateField(StringBuilder builder, StreamState state) + { + double? framerate = null; + if (state.TargetFramerate.HasValue) + { + framerate = Math.Round(state.TargetFramerate.GetValueOrDefault(), 3); + } + else if (state.VideoStream.RealFrameRate.HasValue) + { + framerate = Math.Round(state.VideoStream.RealFrameRate.GetValueOrDefault(), 3); + } + + if (framerate.HasValue) + { + builder.Append(",FRAME-RATE=\"") + .Append(framerate.Value) + .Append('"'); + } + } + private void AppendPlaylist(StringBuilder builder, StreamState state, string url, int bitrate, string subtitleGroup) { builder.Append("#EXT-X-STREAM-INF:BANDWIDTH=") @@ -845,6 +871,8 @@ namespace MediaBrowser.Api.Playback.Hls AppendPlaylistCodecsField(builder, state); + AppendPlaylistFramerateField(builder, state); + if (!string.IsNullOrWhiteSpace(subtitleGroup)) { builder.Append(",SUBTITLES=\"") From 0a2d24aff3d2e78c97b4b2294a418e2cd4a16be1 Mon Sep 17 00:00:00 2001 From: Andreas B <6439218+YouKnowBlom@users.noreply.github.com> Date: Sun, 15 Mar 2020 18:13:19 +0100 Subject: [PATCH 017/517] Add RESOLUTION field to HLS master playlist --- .../Playback/Hls/DynamicHlsService.cs | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index d56b5cbff4..ce25676ff5 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -856,6 +856,24 @@ namespace MediaBrowser.Api.Playback.Hls } } + /// + /// Appends a RESOLUTION field containing the resolution of the output stream. + /// + /// + /// StringBuilder to append the field to. + /// StreamState of the current stream. + private void AppendPlaylistResolutionField(StringBuilder builder, StreamState state) + { + if (state.OutputWidth.HasValue && state.OutputHeight.HasValue) + { + builder.Append(",RESOLUTION=\"") + .Append(state.OutputWidth.GetValueOrDefault()) + .Append('x') + .Append(state.OutputHeight.GetValueOrDefault()) + .Append('"'); + } + } + private void AppendPlaylist(StringBuilder builder, StreamState state, string url, int bitrate, string subtitleGroup) { builder.Append("#EXT-X-STREAM-INF:BANDWIDTH=") @@ -863,14 +881,10 @@ namespace MediaBrowser.Api.Playback.Hls .Append(",AVERAGE-BANDWIDTH=") .Append(bitrate.ToString(CultureInfo.InvariantCulture)); - // tvos wants resolution, codecs, framerate - //if (state.TargetFramerate.HasValue) - //{ - // header += string.Format(",FRAME-RATE=\"{0}\"", state.TargetFramerate.Value.ToString(CultureInfo.InvariantCulture)); - //} - AppendPlaylistCodecsField(builder, state); + AppendPlaylistResolutionField(builder, state); + AppendPlaylistFramerateField(builder, state); if (!string.IsNullOrWhiteSpace(subtitleGroup)) From 2afbbba3f874884e7f249bacb9de458244242380 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 22 Mar 2020 16:00:20 -0400 Subject: [PATCH 018/517] Remove old build script --- build | 197 ---------------------------------------------------------- 1 file changed, 197 deletions(-) delete mode 100755 build diff --git a/build b/build deleted file mode 100755 index 95d5d5c495..0000000000 --- a/build +++ /dev/null @@ -1,197 +0,0 @@ -#!/usr/bin/env bash - -# build - build Jellyfin binaries or packages - -set -o errexit -set -o pipefail - -# The list of possible package actions (except 'clean') -declare -a actions=( 'build' 'package' 'sign' 'publish' ) - -# The list of possible platforms, based on directories under 'deployment/' -declare -a platforms=( $( - find deployment/ -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | sort -) ) - -# The list of standard dependencies required by all build scripts; individual -# action scripts may specify their own dependencies -declare -a dependencies=( 'tar' 'zip' ) - -usage() { - echo -e "build - build Jellyfin binaries or packages" - echo -e "" - echo -e "Usage:" - echo -e " $ build --list-platforms" - echo -e " $ build --list-actions " - echo -e " $ build [-k/--keep-artifacts] [-b/--web-branch ] " - echo -e "" - echo -e "The 'keep-artifacts' option preserves build artifacts, e.g. Docker images for system package builds." - echo -e "The web_branch defaults to the same branch name as the current main branch or can be 'local' to not touch the submodule branching." - echo -e "To build all platforms, use 'all'." - echo -e "To perform all build actions, use 'all'." - echo -e "Build output files are collected at '../bin/'." -} - -# Show usage on stderr with exit 1 on argless -if [[ -z $1 ]]; then - usage >&2 - exit 1 -fi -# Show usage if -h or --help are specified in the args -if [[ $@ =~ '-h' || $@ =~ '--help' ]]; then - usage - exit 0 -fi - -# List all available platforms then exit -if [[ $1 == '--list-platforms' ]]; then - echo -e "Available platforms:" - for platform in ${platforms[@]}; do - echo -e " ${platform}" - done - exit 0 -fi - -# List all available actions for a given platform then exit -if [[ $1 == '--list-actions' ]]; then - platform="$2" - if [[ ! " ${platforms[@]} " =~ " ${platform} " ]]; then - echo "ERROR: Platform ${platform} does not exist." - exit 1 - fi - echo -e "Available actions for platform ${platform}:" - for action in ${actions[@]}; do - if [[ -f deployment/${platform}/${action}.sh ]]; then - echo -e " ${action}" - fi - done - exit 0 -fi - -# Parse keep-artifacts option -if [[ $1 == '-k' || $1 == '--keep-artifacts' ]]; then - keep_artifacts="y" - shift 1 -else - keep_artifacts="n" -fi - -# Parse branch option -if [[ $1 == '-b' || $1 == '--web-branch' ]]; then - web_branch="$2" - shift 2 -else - web_branch="$( git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/' )" -fi - -# Parse platform option -if [[ -n $1 ]]; then - cli_platform="$1" - shift -else - echo "ERROR: A platform must be specified. Use 'all' to specify all platforms." - exit 1 -fi -if [[ ${cli_platform} == 'all' ]]; then - declare -a platform=( ${platforms[@]} ) -else - if [[ ! " ${platforms[@]} " =~ " ${cli_platform} " ]]; then - echo "ERROR: Platform ${cli_platform} is invalid. Use the '--list-platforms' option to list available platforms." - exit 1 - else - declare -a platform=( "${cli_platform}" ) - fi -fi - -# Parse action option -if [[ -n $1 ]]; then - cli_action="$1" - shift -else - echo "ERROR: An action must be specified. Use 'all' to specify all actions." - exit 1 -fi -if [[ ${cli_action} == 'all' ]]; then - declare -a action=( ${actions[@]} ) -else - if [[ ! " ${actions[@]} " =~ " ${cli_action} " ]]; then - echo "ERROR: Action ${cli_action} is invalid. Use the '--list-actions ' option to list available actions." - exit 1 - else - declare -a action=( "${cli_action}" ) - fi -fi - -# Verify required utilities are installed -missing_deps=() -for utility in ${dependencies[@]}; do - if ! which ${utility} &>/dev/null; then - missing_deps+=( ${utility} ) - fi -done - -# Error if we're missing anything -if [[ ${#missing_deps[@]} -gt 0 ]]; then - echo -e "ERROR: This script requires the following missing utilities:" - for utility in ${missing_deps[@]}; do - echo -e " ${utility}" - done - exit 1 -fi - -# Parse platform-specific dependencies -for target_platform in ${platform[@]}; do - # Read platform-specific dependencies - if [[ -f deployment/${target_platform}/dependencies.txt ]]; then - platform_dependencies="$( grep -v '^#' deployment/${target_platform}/dependencies.txt )" - - # Verify required utilities are installed - missing_deps=() - for utility in ${platform_dependencies[@]}; do - if ! which ${utility} &>/dev/null; then - missing_deps+=( ${utility} ) - fi - done - - # Error if we're missing anything - if [[ ${#missing_deps[@]} -gt 0 ]]; then - echo -e "ERROR: The ${target_platform} platform requires the following utilities:" - for utility in ${missing_deps[@]}; do - echo -e " ${utility}" - done - exit 1 - fi - fi -done - -# Execute each platform and action in order, if said action is enabled -pushd deployment/ -for target_platform in ${platform[@]}; do - echo -e "> Processing platform ${target_platform}" - date_start=$( date +%s ) - pushd ${target_platform} - cleanup() { - echo -e ">> Processing action clean" - if [[ -f clean.sh && -x clean.sh ]]; then - ./clean.sh ${keep_artifacts} - fi - } - trap cleanup EXIT INT - for target_action in ${action[@]}; do - echo -e ">> Processing action ${target_action}" - if [[ -f ${target_action}.sh && -x ${target_action}.sh ]]; then - ./${target_action}.sh web_branch=${web_branch} - fi - done - if [[ -d pkg-dist/ ]]; then - echo -e ">> Collecting build artifacts" - target_dir="../../../bin/${target_platform}" - mkdir -p ${target_dir} - mv pkg-dist/* ${target_dir}/ - fi - cleanup - date_end=$( date +%s ) - echo -e "> Completed platform ${target_platform} in $( expr ${date_end} - ${date_start} ) seconds." - popd -done -popd From 28f7df652015013ff5cedb10971fb69c8e41d2b1 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 22 Mar 2020 16:00:52 -0400 Subject: [PATCH 019/517] Move all old deployment stuff to a new folder --- .../fedora-package-x64/pkg-src/restart.sh | 36 ------------------- deployment/{ => old}/README.md | 0 .../{ => old}/centos-package-x64/Dockerfile | 0 .../{ => old}/centos-package-x64/clean.sh | 0 .../centos-package-x64/dependencies.txt | 0 .../centos-package-x64/docker-build.sh | 0 .../{ => old}/centos-package-x64/package.sh | 0 .../{ => old}/centos-package-x64/pkg-src | 0 .../debian-package-arm64/Dockerfile.amd64 | 0 .../debian-package-arm64/Dockerfile.arm64 | 0 .../{ => old}/debian-package-arm64/clean.sh | 0 .../debian-package-arm64/dependencies.txt | 0 .../debian-package-arm64/docker-build.sh | 0 .../{ => old}/debian-package-arm64/package.sh | 0 .../{ => old}/debian-package-arm64/pkg-src | 0 .../debian-package-armhf/Dockerfile.amd64 | 0 .../debian-package-armhf/Dockerfile.armhf | 0 .../{ => old}/debian-package-armhf/clean.sh | 0 .../debian-package-armhf/dependencies.txt | 0 .../debian-package-armhf/docker-build.sh | 0 .../{ => old}/debian-package-armhf/package.sh | 0 .../{ => old}/debian-package-armhf/pkg-src | 0 .../{ => old}/debian-package-x64/Dockerfile | 0 .../{ => old}/debian-package-x64/clean.sh | 0 .../debian-package-x64/dependencies.txt | 0 .../debian-package-x64/docker-build.sh | 0 .../{ => old}/debian-package-x64/package.sh | 0 .../debian-package-x64/pkg-src/changelog | 0 .../debian-package-x64/pkg-src/compat | 0 .../debian-package-x64/pkg-src/conf/jellyfin | 0 .../pkg-src/conf/jellyfin-sudoers | 0 .../pkg-src/conf/jellyfin.service.conf | 0 .../pkg-src/conf/logging.json | 0 .../debian-package-x64/pkg-src/control | 0 .../debian-package-x64/pkg-src/copyright | 0 .../debian-package-x64/pkg-src/gbp.conf | 0 .../debian-package-x64/pkg-src/install | 0 .../debian-package-x64/pkg-src/jellyfin.init | 0 .../pkg-src/jellyfin.service | 0 .../pkg-src/jellyfin.upstart | 0 .../debian-package-x64/pkg-src/po/POTFILES.in | 0 .../pkg-src/po/templates.pot | 0 .../debian-package-x64/pkg-src/postinst | 0 .../debian-package-x64/pkg-src/postrm | 0 .../debian-package-x64/pkg-src/preinst | 0 .../debian-package-x64/pkg-src/prerm | 0 .../debian-package-x64/pkg-src/rules | 0 .../pkg-src/source.lintian-overrides | 0 .../debian-package-x64/pkg-src/source/format | 0 .../debian-package-x64/pkg-src/source/options | 0 .../{ => old}/fedora-package-x64/Dockerfile | 0 .../{ => old}/fedora-package-x64/clean.sh | 0 .../fedora-package-x64/dependencies.txt | 0 .../fedora-package-x64/docker-build.sh | 0 .../{ => old}/fedora-package-x64/package.sh | 0 .../fedora-package-x64/pkg-src/.gitignore | 0 .../fedora-package-x64/pkg-src/README.md | 0 .../pkg-src/jellyfin-firewalld.xml | 0 .../fedora-package-x64/pkg-src/jellyfin.env | 0 .../pkg-src/jellyfin.override.conf | 0 .../pkg-src/jellyfin.service | 0 .../fedora-package-x64/pkg-src/jellyfin.spec | 0 .../pkg-src/jellyfin.sudoers | 0 .../fedora-package-x64/pkg-src}/restart.sh | 0 deployment/{ => old}/linux-x64/Dockerfile | 0 deployment/{ => old}/linux-x64/clean.sh | 0 .../{ => old}/linux-x64/dependencies.txt | 0 .../{ => old}/linux-x64/docker-build.sh | 0 deployment/{ => old}/linux-x64/package.sh | 0 deployment/{ => old}/macos/Dockerfile | 0 deployment/{ => old}/macos/clean.sh | 0 deployment/{ => old}/macos/dependencies.txt | 0 deployment/{ => old}/macos/docker-build.sh | 0 deployment/{ => old}/macos/package.sh | 0 deployment/{ => old}/portable/Dockerfile | 0 deployment/{ => old}/portable/clean.sh | 0 .../{ => old}/portable/dependencies.txt | 0 deployment/{ => old}/portable/docker-build.sh | 0 deployment/{ => old}/portable/package.sh | 0 .../ubuntu-package-arm64/Dockerfile.amd64 | 0 .../ubuntu-package-arm64/Dockerfile.arm64 | 0 .../{ => old}/ubuntu-package-arm64/clean.sh | 0 .../ubuntu-package-arm64/dependencies.txt | 0 .../ubuntu-package-arm64/docker-build.sh | 0 .../{ => old}/ubuntu-package-arm64/package.sh | 0 .../{ => old}/ubuntu-package-arm64/pkg-src | 0 .../ubuntu-package-armhf/Dockerfile.amd64 | 0 .../ubuntu-package-armhf/Dockerfile.armhf | 0 .../{ => old}/ubuntu-package-armhf/clean.sh | 0 .../ubuntu-package-armhf/dependencies.txt | 0 .../ubuntu-package-armhf/docker-build.sh | 0 .../{ => old}/ubuntu-package-armhf/package.sh | 0 .../{ => old}/ubuntu-package-armhf/pkg-src | 0 .../{ => old}/ubuntu-package-x64/Dockerfile | 0 .../{ => old}/ubuntu-package-x64/clean.sh | 0 .../ubuntu-package-x64/dependencies.txt | 0 .../ubuntu-package-x64/docker-build.sh | 0 .../{ => old}/ubuntu-package-x64/package.sh | 0 .../{ => old}/ubuntu-package-x64/pkg-src | 0 .../unraid/docker-templates/README.md | 0 .../unraid/docker-templates/jellyfin.xml | 0 deployment/{ => old}/win-x64/Dockerfile | 0 deployment/{ => old}/win-x64/clean.sh | 0 deployment/{ => old}/win-x64/dependencies.txt | 0 deployment/{ => old}/win-x64/docker-build.sh | 0 deployment/{ => old}/win-x64/package.sh | 0 deployment/{ => old}/win-x86/Dockerfile | 0 deployment/{ => old}/win-x86/clean.sh | 0 deployment/{ => old}/win-x86/dependencies.txt | 0 deployment/{ => old}/win-x86/docker-build.sh | 0 deployment/{ => old}/win-x86/package.sh | 0 .../{ => old}/windows/build-jellyfin.ps1 | 0 deployment/{ => old}/windows/dependencies.txt | 0 .../windows/dialogs/confirmation.nsddef | 0 .../windows/dialogs/confirmation.nsdinc | 0 .../windows/dialogs/service-config.nsddef | 0 .../windows/dialogs/service-config.nsdinc | 0 .../windows/dialogs/setuptype.nsddef | 0 .../windows/dialogs/setuptype.nsdinc | 0 .../{ => old}/windows/helpers/ShowError.nsh | 0 .../{ => old}/windows/helpers/StrSlash.nsh | 0 deployment/{ => old}/windows/jellyfin.nsi | 0 .../windows/legacy/install-jellyfin.ps1 | 0 .../{ => old}/windows/legacy/install.bat | 0 124 files changed, 36 deletions(-) delete mode 100755 deployment/fedora-package-x64/pkg-src/restart.sh rename deployment/{ => old}/README.md (100%) rename deployment/{ => old}/centos-package-x64/Dockerfile (100%) rename deployment/{ => old}/centos-package-x64/clean.sh (100%) rename deployment/{ => old}/centos-package-x64/dependencies.txt (100%) rename deployment/{ => old}/centos-package-x64/docker-build.sh (100%) rename deployment/{ => old}/centos-package-x64/package.sh (100%) rename deployment/{ => old}/centos-package-x64/pkg-src (100%) rename deployment/{ => old}/debian-package-arm64/Dockerfile.amd64 (100%) rename deployment/{ => old}/debian-package-arm64/Dockerfile.arm64 (100%) rename deployment/{ => old}/debian-package-arm64/clean.sh (100%) rename deployment/{ => old}/debian-package-arm64/dependencies.txt (100%) rename deployment/{ => old}/debian-package-arm64/docker-build.sh (100%) rename deployment/{ => old}/debian-package-arm64/package.sh (100%) rename deployment/{ => old}/debian-package-arm64/pkg-src (100%) rename deployment/{ => old}/debian-package-armhf/Dockerfile.amd64 (100%) rename deployment/{ => old}/debian-package-armhf/Dockerfile.armhf (100%) rename deployment/{ => old}/debian-package-armhf/clean.sh (100%) rename deployment/{ => old}/debian-package-armhf/dependencies.txt (100%) rename deployment/{ => old}/debian-package-armhf/docker-build.sh (100%) rename deployment/{ => old}/debian-package-armhf/package.sh (100%) rename deployment/{ => old}/debian-package-armhf/pkg-src (100%) rename deployment/{ => old}/debian-package-x64/Dockerfile (100%) rename deployment/{ => old}/debian-package-x64/clean.sh (100%) rename deployment/{ => old}/debian-package-x64/dependencies.txt (100%) rename deployment/{ => old}/debian-package-x64/docker-build.sh (100%) rename deployment/{ => old}/debian-package-x64/package.sh (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/changelog (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/compat (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/conf/jellyfin (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/conf/jellyfin-sudoers (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/conf/jellyfin.service.conf (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/conf/logging.json (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/control (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/copyright (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/gbp.conf (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/install (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/jellyfin.init (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/jellyfin.service (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/jellyfin.upstart (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/po/POTFILES.in (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/po/templates.pot (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/postinst (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/postrm (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/preinst (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/prerm (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/rules (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/source.lintian-overrides (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/source/format (100%) rename deployment/{ => old}/debian-package-x64/pkg-src/source/options (100%) rename deployment/{ => old}/fedora-package-x64/Dockerfile (100%) rename deployment/{ => old}/fedora-package-x64/clean.sh (100%) rename deployment/{ => old}/fedora-package-x64/dependencies.txt (100%) rename deployment/{ => old}/fedora-package-x64/docker-build.sh (100%) rename deployment/{ => old}/fedora-package-x64/package.sh (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/.gitignore (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/README.md (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/jellyfin-firewalld.xml (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/jellyfin.env (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/jellyfin.override.conf (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/jellyfin.service (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/jellyfin.spec (100%) rename deployment/{ => old}/fedora-package-x64/pkg-src/jellyfin.sudoers (100%) rename deployment/{debian-package-x64/pkg-src/bin => old/fedora-package-x64/pkg-src}/restart.sh (100%) rename deployment/{ => old}/linux-x64/Dockerfile (100%) rename deployment/{ => old}/linux-x64/clean.sh (100%) rename deployment/{ => old}/linux-x64/dependencies.txt (100%) rename deployment/{ => old}/linux-x64/docker-build.sh (100%) rename deployment/{ => old}/linux-x64/package.sh (100%) rename deployment/{ => old}/macos/Dockerfile (100%) rename deployment/{ => old}/macos/clean.sh (100%) rename deployment/{ => old}/macos/dependencies.txt (100%) rename deployment/{ => old}/macos/docker-build.sh (100%) rename deployment/{ => old}/macos/package.sh (100%) rename deployment/{ => old}/portable/Dockerfile (100%) rename deployment/{ => old}/portable/clean.sh (100%) rename deployment/{ => old}/portable/dependencies.txt (100%) rename deployment/{ => old}/portable/docker-build.sh (100%) rename deployment/{ => old}/portable/package.sh (100%) rename deployment/{ => old}/ubuntu-package-arm64/Dockerfile.amd64 (100%) rename deployment/{ => old}/ubuntu-package-arm64/Dockerfile.arm64 (100%) rename deployment/{ => old}/ubuntu-package-arm64/clean.sh (100%) rename deployment/{ => old}/ubuntu-package-arm64/dependencies.txt (100%) rename deployment/{ => old}/ubuntu-package-arm64/docker-build.sh (100%) rename deployment/{ => old}/ubuntu-package-arm64/package.sh (100%) rename deployment/{ => old}/ubuntu-package-arm64/pkg-src (100%) rename deployment/{ => old}/ubuntu-package-armhf/Dockerfile.amd64 (100%) rename deployment/{ => old}/ubuntu-package-armhf/Dockerfile.armhf (100%) rename deployment/{ => old}/ubuntu-package-armhf/clean.sh (100%) rename deployment/{ => old}/ubuntu-package-armhf/dependencies.txt (100%) rename deployment/{ => old}/ubuntu-package-armhf/docker-build.sh (100%) rename deployment/{ => old}/ubuntu-package-armhf/package.sh (100%) rename deployment/{ => old}/ubuntu-package-armhf/pkg-src (100%) rename deployment/{ => old}/ubuntu-package-x64/Dockerfile (100%) rename deployment/{ => old}/ubuntu-package-x64/clean.sh (100%) rename deployment/{ => old}/ubuntu-package-x64/dependencies.txt (100%) rename deployment/{ => old}/ubuntu-package-x64/docker-build.sh (100%) rename deployment/{ => old}/ubuntu-package-x64/package.sh (100%) rename deployment/{ => old}/ubuntu-package-x64/pkg-src (100%) rename deployment/{ => old}/unraid/docker-templates/README.md (100%) rename deployment/{ => old}/unraid/docker-templates/jellyfin.xml (100%) rename deployment/{ => old}/win-x64/Dockerfile (100%) rename deployment/{ => old}/win-x64/clean.sh (100%) rename deployment/{ => old}/win-x64/dependencies.txt (100%) rename deployment/{ => old}/win-x64/docker-build.sh (100%) rename deployment/{ => old}/win-x64/package.sh (100%) rename deployment/{ => old}/win-x86/Dockerfile (100%) rename deployment/{ => old}/win-x86/clean.sh (100%) rename deployment/{ => old}/win-x86/dependencies.txt (100%) rename deployment/{ => old}/win-x86/docker-build.sh (100%) rename deployment/{ => old}/win-x86/package.sh (100%) rename deployment/{ => old}/windows/build-jellyfin.ps1 (100%) rename deployment/{ => old}/windows/dependencies.txt (100%) rename deployment/{ => old}/windows/dialogs/confirmation.nsddef (100%) rename deployment/{ => old}/windows/dialogs/confirmation.nsdinc (100%) rename deployment/{ => old}/windows/dialogs/service-config.nsddef (100%) rename deployment/{ => old}/windows/dialogs/service-config.nsdinc (100%) rename deployment/{ => old}/windows/dialogs/setuptype.nsddef (100%) rename deployment/{ => old}/windows/dialogs/setuptype.nsdinc (100%) rename deployment/{ => old}/windows/helpers/ShowError.nsh (100%) rename deployment/{ => old}/windows/helpers/StrSlash.nsh (100%) rename deployment/{ => old}/windows/jellyfin.nsi (100%) rename deployment/{ => old}/windows/legacy/install-jellyfin.ps1 (100%) rename deployment/{ => old}/windows/legacy/install.bat (100%) diff --git a/deployment/fedora-package-x64/pkg-src/restart.sh b/deployment/fedora-package-x64/pkg-src/restart.sh deleted file mode 100755 index 9b64b6d728..0000000000 --- a/deployment/fedora-package-x64/pkg-src/restart.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# restart.sh - Jellyfin server restart script -# Part of the Jellyfin project (https://github.com/jellyfin) -# -# This script restarts the Jellyfin daemon on Linux when using -# the Restart button on the admin dashboard. It supports the -# systemctl, service, and traditional /etc/init.d (sysv) restart -# methods, chosen automatically by which one is found first (in -# that order). -# -# This script is used by the Debian/Ubuntu/Fedora/CentOS packages. - -get_service_command() { - for command in systemctl service; do - if which $command &>/dev/null; then - echo $command && return - fi - done - echo "sysv" -} - -cmd="$( get_service_command )" -echo "Detected service control platform '$cmd'; using it to restart Jellyfin..." -case $cmd in - 'systemctl') - echo "sleep 2; /usr/bin/sudo $( which systemctl ) restart jellyfin" | at now - ;; - 'service') - echo "sleep 2; /usr/bin/sudo $( which service ) jellyfin restart" | at now - ;; - 'sysv') - echo "sleep 2; /usr/bin/sudo /etc/init.d/jellyfin restart" | at now - ;; -esac -exit 0 diff --git a/deployment/README.md b/deployment/old/README.md similarity index 100% rename from deployment/README.md rename to deployment/old/README.md diff --git a/deployment/centos-package-x64/Dockerfile b/deployment/old/centos-package-x64/Dockerfile similarity index 100% rename from deployment/centos-package-x64/Dockerfile rename to deployment/old/centos-package-x64/Dockerfile diff --git a/deployment/centos-package-x64/clean.sh b/deployment/old/centos-package-x64/clean.sh similarity index 100% rename from deployment/centos-package-x64/clean.sh rename to deployment/old/centos-package-x64/clean.sh diff --git a/deployment/centos-package-x64/dependencies.txt b/deployment/old/centos-package-x64/dependencies.txt similarity index 100% rename from deployment/centos-package-x64/dependencies.txt rename to deployment/old/centos-package-x64/dependencies.txt diff --git a/deployment/centos-package-x64/docker-build.sh b/deployment/old/centos-package-x64/docker-build.sh similarity index 100% rename from deployment/centos-package-x64/docker-build.sh rename to deployment/old/centos-package-x64/docker-build.sh diff --git a/deployment/centos-package-x64/package.sh b/deployment/old/centos-package-x64/package.sh similarity index 100% rename from deployment/centos-package-x64/package.sh rename to deployment/old/centos-package-x64/package.sh diff --git a/deployment/centos-package-x64/pkg-src b/deployment/old/centos-package-x64/pkg-src similarity index 100% rename from deployment/centos-package-x64/pkg-src rename to deployment/old/centos-package-x64/pkg-src diff --git a/deployment/debian-package-arm64/Dockerfile.amd64 b/deployment/old/debian-package-arm64/Dockerfile.amd64 similarity index 100% rename from deployment/debian-package-arm64/Dockerfile.amd64 rename to deployment/old/debian-package-arm64/Dockerfile.amd64 diff --git a/deployment/debian-package-arm64/Dockerfile.arm64 b/deployment/old/debian-package-arm64/Dockerfile.arm64 similarity index 100% rename from deployment/debian-package-arm64/Dockerfile.arm64 rename to deployment/old/debian-package-arm64/Dockerfile.arm64 diff --git a/deployment/debian-package-arm64/clean.sh b/deployment/old/debian-package-arm64/clean.sh similarity index 100% rename from deployment/debian-package-arm64/clean.sh rename to deployment/old/debian-package-arm64/clean.sh diff --git a/deployment/debian-package-arm64/dependencies.txt b/deployment/old/debian-package-arm64/dependencies.txt similarity index 100% rename from deployment/debian-package-arm64/dependencies.txt rename to deployment/old/debian-package-arm64/dependencies.txt diff --git a/deployment/debian-package-arm64/docker-build.sh b/deployment/old/debian-package-arm64/docker-build.sh similarity index 100% rename from deployment/debian-package-arm64/docker-build.sh rename to deployment/old/debian-package-arm64/docker-build.sh diff --git a/deployment/debian-package-arm64/package.sh b/deployment/old/debian-package-arm64/package.sh similarity index 100% rename from deployment/debian-package-arm64/package.sh rename to deployment/old/debian-package-arm64/package.sh diff --git a/deployment/debian-package-arm64/pkg-src b/deployment/old/debian-package-arm64/pkg-src similarity index 100% rename from deployment/debian-package-arm64/pkg-src rename to deployment/old/debian-package-arm64/pkg-src diff --git a/deployment/debian-package-armhf/Dockerfile.amd64 b/deployment/old/debian-package-armhf/Dockerfile.amd64 similarity index 100% rename from deployment/debian-package-armhf/Dockerfile.amd64 rename to deployment/old/debian-package-armhf/Dockerfile.amd64 diff --git a/deployment/debian-package-armhf/Dockerfile.armhf b/deployment/old/debian-package-armhf/Dockerfile.armhf similarity index 100% rename from deployment/debian-package-armhf/Dockerfile.armhf rename to deployment/old/debian-package-armhf/Dockerfile.armhf diff --git a/deployment/debian-package-armhf/clean.sh b/deployment/old/debian-package-armhf/clean.sh similarity index 100% rename from deployment/debian-package-armhf/clean.sh rename to deployment/old/debian-package-armhf/clean.sh diff --git a/deployment/debian-package-armhf/dependencies.txt b/deployment/old/debian-package-armhf/dependencies.txt similarity index 100% rename from deployment/debian-package-armhf/dependencies.txt rename to deployment/old/debian-package-armhf/dependencies.txt diff --git a/deployment/debian-package-armhf/docker-build.sh b/deployment/old/debian-package-armhf/docker-build.sh similarity index 100% rename from deployment/debian-package-armhf/docker-build.sh rename to deployment/old/debian-package-armhf/docker-build.sh diff --git a/deployment/debian-package-armhf/package.sh b/deployment/old/debian-package-armhf/package.sh similarity index 100% rename from deployment/debian-package-armhf/package.sh rename to deployment/old/debian-package-armhf/package.sh diff --git a/deployment/debian-package-armhf/pkg-src b/deployment/old/debian-package-armhf/pkg-src similarity index 100% rename from deployment/debian-package-armhf/pkg-src rename to deployment/old/debian-package-armhf/pkg-src diff --git a/deployment/debian-package-x64/Dockerfile b/deployment/old/debian-package-x64/Dockerfile similarity index 100% rename from deployment/debian-package-x64/Dockerfile rename to deployment/old/debian-package-x64/Dockerfile diff --git a/deployment/debian-package-x64/clean.sh b/deployment/old/debian-package-x64/clean.sh similarity index 100% rename from deployment/debian-package-x64/clean.sh rename to deployment/old/debian-package-x64/clean.sh diff --git a/deployment/debian-package-x64/dependencies.txt b/deployment/old/debian-package-x64/dependencies.txt similarity index 100% rename from deployment/debian-package-x64/dependencies.txt rename to deployment/old/debian-package-x64/dependencies.txt diff --git a/deployment/debian-package-x64/docker-build.sh b/deployment/old/debian-package-x64/docker-build.sh similarity index 100% rename from deployment/debian-package-x64/docker-build.sh rename to deployment/old/debian-package-x64/docker-build.sh diff --git a/deployment/debian-package-x64/package.sh b/deployment/old/debian-package-x64/package.sh similarity index 100% rename from deployment/debian-package-x64/package.sh rename to deployment/old/debian-package-x64/package.sh diff --git a/deployment/debian-package-x64/pkg-src/changelog b/deployment/old/debian-package-x64/pkg-src/changelog similarity index 100% rename from deployment/debian-package-x64/pkg-src/changelog rename to deployment/old/debian-package-x64/pkg-src/changelog diff --git a/deployment/debian-package-x64/pkg-src/compat b/deployment/old/debian-package-x64/pkg-src/compat similarity index 100% rename from deployment/debian-package-x64/pkg-src/compat rename to deployment/old/debian-package-x64/pkg-src/compat diff --git a/deployment/debian-package-x64/pkg-src/conf/jellyfin b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin similarity index 100% rename from deployment/debian-package-x64/pkg-src/conf/jellyfin rename to deployment/old/debian-package-x64/pkg-src/conf/jellyfin diff --git a/deployment/debian-package-x64/pkg-src/conf/jellyfin-sudoers b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers similarity index 100% rename from deployment/debian-package-x64/pkg-src/conf/jellyfin-sudoers rename to deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers diff --git a/deployment/debian-package-x64/pkg-src/conf/jellyfin.service.conf b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf similarity index 100% rename from deployment/debian-package-x64/pkg-src/conf/jellyfin.service.conf rename to deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf diff --git a/deployment/debian-package-x64/pkg-src/conf/logging.json b/deployment/old/debian-package-x64/pkg-src/conf/logging.json similarity index 100% rename from deployment/debian-package-x64/pkg-src/conf/logging.json rename to deployment/old/debian-package-x64/pkg-src/conf/logging.json diff --git a/deployment/debian-package-x64/pkg-src/control b/deployment/old/debian-package-x64/pkg-src/control similarity index 100% rename from deployment/debian-package-x64/pkg-src/control rename to deployment/old/debian-package-x64/pkg-src/control diff --git a/deployment/debian-package-x64/pkg-src/copyright b/deployment/old/debian-package-x64/pkg-src/copyright similarity index 100% rename from deployment/debian-package-x64/pkg-src/copyright rename to deployment/old/debian-package-x64/pkg-src/copyright diff --git a/deployment/debian-package-x64/pkg-src/gbp.conf b/deployment/old/debian-package-x64/pkg-src/gbp.conf similarity index 100% rename from deployment/debian-package-x64/pkg-src/gbp.conf rename to deployment/old/debian-package-x64/pkg-src/gbp.conf diff --git a/deployment/debian-package-x64/pkg-src/install b/deployment/old/debian-package-x64/pkg-src/install similarity index 100% rename from deployment/debian-package-x64/pkg-src/install rename to deployment/old/debian-package-x64/pkg-src/install diff --git a/deployment/debian-package-x64/pkg-src/jellyfin.init b/deployment/old/debian-package-x64/pkg-src/jellyfin.init similarity index 100% rename from deployment/debian-package-x64/pkg-src/jellyfin.init rename to deployment/old/debian-package-x64/pkg-src/jellyfin.init diff --git a/deployment/debian-package-x64/pkg-src/jellyfin.service b/deployment/old/debian-package-x64/pkg-src/jellyfin.service similarity index 100% rename from deployment/debian-package-x64/pkg-src/jellyfin.service rename to deployment/old/debian-package-x64/pkg-src/jellyfin.service diff --git a/deployment/debian-package-x64/pkg-src/jellyfin.upstart b/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart similarity index 100% rename from deployment/debian-package-x64/pkg-src/jellyfin.upstart rename to deployment/old/debian-package-x64/pkg-src/jellyfin.upstart diff --git a/deployment/debian-package-x64/pkg-src/po/POTFILES.in b/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in similarity index 100% rename from deployment/debian-package-x64/pkg-src/po/POTFILES.in rename to deployment/old/debian-package-x64/pkg-src/po/POTFILES.in diff --git a/deployment/debian-package-x64/pkg-src/po/templates.pot b/deployment/old/debian-package-x64/pkg-src/po/templates.pot similarity index 100% rename from deployment/debian-package-x64/pkg-src/po/templates.pot rename to deployment/old/debian-package-x64/pkg-src/po/templates.pot diff --git a/deployment/debian-package-x64/pkg-src/postinst b/deployment/old/debian-package-x64/pkg-src/postinst similarity index 100% rename from deployment/debian-package-x64/pkg-src/postinst rename to deployment/old/debian-package-x64/pkg-src/postinst diff --git a/deployment/debian-package-x64/pkg-src/postrm b/deployment/old/debian-package-x64/pkg-src/postrm similarity index 100% rename from deployment/debian-package-x64/pkg-src/postrm rename to deployment/old/debian-package-x64/pkg-src/postrm diff --git a/deployment/debian-package-x64/pkg-src/preinst b/deployment/old/debian-package-x64/pkg-src/preinst similarity index 100% rename from deployment/debian-package-x64/pkg-src/preinst rename to deployment/old/debian-package-x64/pkg-src/preinst diff --git a/deployment/debian-package-x64/pkg-src/prerm b/deployment/old/debian-package-x64/pkg-src/prerm similarity index 100% rename from deployment/debian-package-x64/pkg-src/prerm rename to deployment/old/debian-package-x64/pkg-src/prerm diff --git a/deployment/debian-package-x64/pkg-src/rules b/deployment/old/debian-package-x64/pkg-src/rules similarity index 100% rename from deployment/debian-package-x64/pkg-src/rules rename to deployment/old/debian-package-x64/pkg-src/rules diff --git a/deployment/debian-package-x64/pkg-src/source.lintian-overrides b/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides similarity index 100% rename from deployment/debian-package-x64/pkg-src/source.lintian-overrides rename to deployment/old/debian-package-x64/pkg-src/source.lintian-overrides diff --git a/deployment/debian-package-x64/pkg-src/source/format b/deployment/old/debian-package-x64/pkg-src/source/format similarity index 100% rename from deployment/debian-package-x64/pkg-src/source/format rename to deployment/old/debian-package-x64/pkg-src/source/format diff --git a/deployment/debian-package-x64/pkg-src/source/options b/deployment/old/debian-package-x64/pkg-src/source/options similarity index 100% rename from deployment/debian-package-x64/pkg-src/source/options rename to deployment/old/debian-package-x64/pkg-src/source/options diff --git a/deployment/fedora-package-x64/Dockerfile b/deployment/old/fedora-package-x64/Dockerfile similarity index 100% rename from deployment/fedora-package-x64/Dockerfile rename to deployment/old/fedora-package-x64/Dockerfile diff --git a/deployment/fedora-package-x64/clean.sh b/deployment/old/fedora-package-x64/clean.sh similarity index 100% rename from deployment/fedora-package-x64/clean.sh rename to deployment/old/fedora-package-x64/clean.sh diff --git a/deployment/fedora-package-x64/dependencies.txt b/deployment/old/fedora-package-x64/dependencies.txt similarity index 100% rename from deployment/fedora-package-x64/dependencies.txt rename to deployment/old/fedora-package-x64/dependencies.txt diff --git a/deployment/fedora-package-x64/docker-build.sh b/deployment/old/fedora-package-x64/docker-build.sh similarity index 100% rename from deployment/fedora-package-x64/docker-build.sh rename to deployment/old/fedora-package-x64/docker-build.sh diff --git a/deployment/fedora-package-x64/package.sh b/deployment/old/fedora-package-x64/package.sh similarity index 100% rename from deployment/fedora-package-x64/package.sh rename to deployment/old/fedora-package-x64/package.sh diff --git a/deployment/fedora-package-x64/pkg-src/.gitignore b/deployment/old/fedora-package-x64/pkg-src/.gitignore similarity index 100% rename from deployment/fedora-package-x64/pkg-src/.gitignore rename to deployment/old/fedora-package-x64/pkg-src/.gitignore diff --git a/deployment/fedora-package-x64/pkg-src/README.md b/deployment/old/fedora-package-x64/pkg-src/README.md similarity index 100% rename from deployment/fedora-package-x64/pkg-src/README.md rename to deployment/old/fedora-package-x64/pkg-src/README.md diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin-firewalld.xml b/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml similarity index 100% rename from deployment/fedora-package-x64/pkg-src/jellyfin-firewalld.xml rename to deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.env b/deployment/old/fedora-package-x64/pkg-src/jellyfin.env similarity index 100% rename from deployment/fedora-package-x64/pkg-src/jellyfin.env rename to deployment/old/fedora-package-x64/pkg-src/jellyfin.env diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.override.conf b/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf similarity index 100% rename from deployment/fedora-package-x64/pkg-src/jellyfin.override.conf rename to deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.service b/deployment/old/fedora-package-x64/pkg-src/jellyfin.service similarity index 100% rename from deployment/fedora-package-x64/pkg-src/jellyfin.service rename to deployment/old/fedora-package-x64/pkg-src/jellyfin.service diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec similarity index 100% rename from deployment/fedora-package-x64/pkg-src/jellyfin.spec rename to deployment/old/fedora-package-x64/pkg-src/jellyfin.spec diff --git a/deployment/fedora-package-x64/pkg-src/jellyfin.sudoers b/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers similarity index 100% rename from deployment/fedora-package-x64/pkg-src/jellyfin.sudoers rename to deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers diff --git a/deployment/debian-package-x64/pkg-src/bin/restart.sh b/deployment/old/fedora-package-x64/pkg-src/restart.sh similarity index 100% rename from deployment/debian-package-x64/pkg-src/bin/restart.sh rename to deployment/old/fedora-package-x64/pkg-src/restart.sh diff --git a/deployment/linux-x64/Dockerfile b/deployment/old/linux-x64/Dockerfile similarity index 100% rename from deployment/linux-x64/Dockerfile rename to deployment/old/linux-x64/Dockerfile diff --git a/deployment/linux-x64/clean.sh b/deployment/old/linux-x64/clean.sh similarity index 100% rename from deployment/linux-x64/clean.sh rename to deployment/old/linux-x64/clean.sh diff --git a/deployment/linux-x64/dependencies.txt b/deployment/old/linux-x64/dependencies.txt similarity index 100% rename from deployment/linux-x64/dependencies.txt rename to deployment/old/linux-x64/dependencies.txt diff --git a/deployment/linux-x64/docker-build.sh b/deployment/old/linux-x64/docker-build.sh similarity index 100% rename from deployment/linux-x64/docker-build.sh rename to deployment/old/linux-x64/docker-build.sh diff --git a/deployment/linux-x64/package.sh b/deployment/old/linux-x64/package.sh similarity index 100% rename from deployment/linux-x64/package.sh rename to deployment/old/linux-x64/package.sh diff --git a/deployment/macos/Dockerfile b/deployment/old/macos/Dockerfile similarity index 100% rename from deployment/macos/Dockerfile rename to deployment/old/macos/Dockerfile diff --git a/deployment/macos/clean.sh b/deployment/old/macos/clean.sh similarity index 100% rename from deployment/macos/clean.sh rename to deployment/old/macos/clean.sh diff --git a/deployment/macos/dependencies.txt b/deployment/old/macos/dependencies.txt similarity index 100% rename from deployment/macos/dependencies.txt rename to deployment/old/macos/dependencies.txt diff --git a/deployment/macos/docker-build.sh b/deployment/old/macos/docker-build.sh similarity index 100% rename from deployment/macos/docker-build.sh rename to deployment/old/macos/docker-build.sh diff --git a/deployment/macos/package.sh b/deployment/old/macos/package.sh similarity index 100% rename from deployment/macos/package.sh rename to deployment/old/macos/package.sh diff --git a/deployment/portable/Dockerfile b/deployment/old/portable/Dockerfile similarity index 100% rename from deployment/portable/Dockerfile rename to deployment/old/portable/Dockerfile diff --git a/deployment/portable/clean.sh b/deployment/old/portable/clean.sh similarity index 100% rename from deployment/portable/clean.sh rename to deployment/old/portable/clean.sh diff --git a/deployment/portable/dependencies.txt b/deployment/old/portable/dependencies.txt similarity index 100% rename from deployment/portable/dependencies.txt rename to deployment/old/portable/dependencies.txt diff --git a/deployment/portable/docker-build.sh b/deployment/old/portable/docker-build.sh similarity index 100% rename from deployment/portable/docker-build.sh rename to deployment/old/portable/docker-build.sh diff --git a/deployment/portable/package.sh b/deployment/old/portable/package.sh similarity index 100% rename from deployment/portable/package.sh rename to deployment/old/portable/package.sh diff --git a/deployment/ubuntu-package-arm64/Dockerfile.amd64 b/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 similarity index 100% rename from deployment/ubuntu-package-arm64/Dockerfile.amd64 rename to deployment/old/ubuntu-package-arm64/Dockerfile.amd64 diff --git a/deployment/ubuntu-package-arm64/Dockerfile.arm64 b/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 similarity index 100% rename from deployment/ubuntu-package-arm64/Dockerfile.arm64 rename to deployment/old/ubuntu-package-arm64/Dockerfile.arm64 diff --git a/deployment/ubuntu-package-arm64/clean.sh b/deployment/old/ubuntu-package-arm64/clean.sh similarity index 100% rename from deployment/ubuntu-package-arm64/clean.sh rename to deployment/old/ubuntu-package-arm64/clean.sh diff --git a/deployment/ubuntu-package-arm64/dependencies.txt b/deployment/old/ubuntu-package-arm64/dependencies.txt similarity index 100% rename from deployment/ubuntu-package-arm64/dependencies.txt rename to deployment/old/ubuntu-package-arm64/dependencies.txt diff --git a/deployment/ubuntu-package-arm64/docker-build.sh b/deployment/old/ubuntu-package-arm64/docker-build.sh similarity index 100% rename from deployment/ubuntu-package-arm64/docker-build.sh rename to deployment/old/ubuntu-package-arm64/docker-build.sh diff --git a/deployment/ubuntu-package-arm64/package.sh b/deployment/old/ubuntu-package-arm64/package.sh similarity index 100% rename from deployment/ubuntu-package-arm64/package.sh rename to deployment/old/ubuntu-package-arm64/package.sh diff --git a/deployment/ubuntu-package-arm64/pkg-src b/deployment/old/ubuntu-package-arm64/pkg-src similarity index 100% rename from deployment/ubuntu-package-arm64/pkg-src rename to deployment/old/ubuntu-package-arm64/pkg-src diff --git a/deployment/ubuntu-package-armhf/Dockerfile.amd64 b/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 similarity index 100% rename from deployment/ubuntu-package-armhf/Dockerfile.amd64 rename to deployment/old/ubuntu-package-armhf/Dockerfile.amd64 diff --git a/deployment/ubuntu-package-armhf/Dockerfile.armhf b/deployment/old/ubuntu-package-armhf/Dockerfile.armhf similarity index 100% rename from deployment/ubuntu-package-armhf/Dockerfile.armhf rename to deployment/old/ubuntu-package-armhf/Dockerfile.armhf diff --git a/deployment/ubuntu-package-armhf/clean.sh b/deployment/old/ubuntu-package-armhf/clean.sh similarity index 100% rename from deployment/ubuntu-package-armhf/clean.sh rename to deployment/old/ubuntu-package-armhf/clean.sh diff --git a/deployment/ubuntu-package-armhf/dependencies.txt b/deployment/old/ubuntu-package-armhf/dependencies.txt similarity index 100% rename from deployment/ubuntu-package-armhf/dependencies.txt rename to deployment/old/ubuntu-package-armhf/dependencies.txt diff --git a/deployment/ubuntu-package-armhf/docker-build.sh b/deployment/old/ubuntu-package-armhf/docker-build.sh similarity index 100% rename from deployment/ubuntu-package-armhf/docker-build.sh rename to deployment/old/ubuntu-package-armhf/docker-build.sh diff --git a/deployment/ubuntu-package-armhf/package.sh b/deployment/old/ubuntu-package-armhf/package.sh similarity index 100% rename from deployment/ubuntu-package-armhf/package.sh rename to deployment/old/ubuntu-package-armhf/package.sh diff --git a/deployment/ubuntu-package-armhf/pkg-src b/deployment/old/ubuntu-package-armhf/pkg-src similarity index 100% rename from deployment/ubuntu-package-armhf/pkg-src rename to deployment/old/ubuntu-package-armhf/pkg-src diff --git a/deployment/ubuntu-package-x64/Dockerfile b/deployment/old/ubuntu-package-x64/Dockerfile similarity index 100% rename from deployment/ubuntu-package-x64/Dockerfile rename to deployment/old/ubuntu-package-x64/Dockerfile diff --git a/deployment/ubuntu-package-x64/clean.sh b/deployment/old/ubuntu-package-x64/clean.sh similarity index 100% rename from deployment/ubuntu-package-x64/clean.sh rename to deployment/old/ubuntu-package-x64/clean.sh diff --git a/deployment/ubuntu-package-x64/dependencies.txt b/deployment/old/ubuntu-package-x64/dependencies.txt similarity index 100% rename from deployment/ubuntu-package-x64/dependencies.txt rename to deployment/old/ubuntu-package-x64/dependencies.txt diff --git a/deployment/ubuntu-package-x64/docker-build.sh b/deployment/old/ubuntu-package-x64/docker-build.sh similarity index 100% rename from deployment/ubuntu-package-x64/docker-build.sh rename to deployment/old/ubuntu-package-x64/docker-build.sh diff --git a/deployment/ubuntu-package-x64/package.sh b/deployment/old/ubuntu-package-x64/package.sh similarity index 100% rename from deployment/ubuntu-package-x64/package.sh rename to deployment/old/ubuntu-package-x64/package.sh diff --git a/deployment/ubuntu-package-x64/pkg-src b/deployment/old/ubuntu-package-x64/pkg-src similarity index 100% rename from deployment/ubuntu-package-x64/pkg-src rename to deployment/old/ubuntu-package-x64/pkg-src diff --git a/deployment/unraid/docker-templates/README.md b/deployment/old/unraid/docker-templates/README.md similarity index 100% rename from deployment/unraid/docker-templates/README.md rename to deployment/old/unraid/docker-templates/README.md diff --git a/deployment/unraid/docker-templates/jellyfin.xml b/deployment/old/unraid/docker-templates/jellyfin.xml similarity index 100% rename from deployment/unraid/docker-templates/jellyfin.xml rename to deployment/old/unraid/docker-templates/jellyfin.xml diff --git a/deployment/win-x64/Dockerfile b/deployment/old/win-x64/Dockerfile similarity index 100% rename from deployment/win-x64/Dockerfile rename to deployment/old/win-x64/Dockerfile diff --git a/deployment/win-x64/clean.sh b/deployment/old/win-x64/clean.sh similarity index 100% rename from deployment/win-x64/clean.sh rename to deployment/old/win-x64/clean.sh diff --git a/deployment/win-x64/dependencies.txt b/deployment/old/win-x64/dependencies.txt similarity index 100% rename from deployment/win-x64/dependencies.txt rename to deployment/old/win-x64/dependencies.txt diff --git a/deployment/win-x64/docker-build.sh b/deployment/old/win-x64/docker-build.sh similarity index 100% rename from deployment/win-x64/docker-build.sh rename to deployment/old/win-x64/docker-build.sh diff --git a/deployment/win-x64/package.sh b/deployment/old/win-x64/package.sh similarity index 100% rename from deployment/win-x64/package.sh rename to deployment/old/win-x64/package.sh diff --git a/deployment/win-x86/Dockerfile b/deployment/old/win-x86/Dockerfile similarity index 100% rename from deployment/win-x86/Dockerfile rename to deployment/old/win-x86/Dockerfile diff --git a/deployment/win-x86/clean.sh b/deployment/old/win-x86/clean.sh similarity index 100% rename from deployment/win-x86/clean.sh rename to deployment/old/win-x86/clean.sh diff --git a/deployment/win-x86/dependencies.txt b/deployment/old/win-x86/dependencies.txt similarity index 100% rename from deployment/win-x86/dependencies.txt rename to deployment/old/win-x86/dependencies.txt diff --git a/deployment/win-x86/docker-build.sh b/deployment/old/win-x86/docker-build.sh similarity index 100% rename from deployment/win-x86/docker-build.sh rename to deployment/old/win-x86/docker-build.sh diff --git a/deployment/win-x86/package.sh b/deployment/old/win-x86/package.sh similarity index 100% rename from deployment/win-x86/package.sh rename to deployment/old/win-x86/package.sh diff --git a/deployment/windows/build-jellyfin.ps1 b/deployment/old/windows/build-jellyfin.ps1 similarity index 100% rename from deployment/windows/build-jellyfin.ps1 rename to deployment/old/windows/build-jellyfin.ps1 diff --git a/deployment/windows/dependencies.txt b/deployment/old/windows/dependencies.txt similarity index 100% rename from deployment/windows/dependencies.txt rename to deployment/old/windows/dependencies.txt diff --git a/deployment/windows/dialogs/confirmation.nsddef b/deployment/old/windows/dialogs/confirmation.nsddef similarity index 100% rename from deployment/windows/dialogs/confirmation.nsddef rename to deployment/old/windows/dialogs/confirmation.nsddef diff --git a/deployment/windows/dialogs/confirmation.nsdinc b/deployment/old/windows/dialogs/confirmation.nsdinc similarity index 100% rename from deployment/windows/dialogs/confirmation.nsdinc rename to deployment/old/windows/dialogs/confirmation.nsdinc diff --git a/deployment/windows/dialogs/service-config.nsddef b/deployment/old/windows/dialogs/service-config.nsddef similarity index 100% rename from deployment/windows/dialogs/service-config.nsddef rename to deployment/old/windows/dialogs/service-config.nsddef diff --git a/deployment/windows/dialogs/service-config.nsdinc b/deployment/old/windows/dialogs/service-config.nsdinc similarity index 100% rename from deployment/windows/dialogs/service-config.nsdinc rename to deployment/old/windows/dialogs/service-config.nsdinc diff --git a/deployment/windows/dialogs/setuptype.nsddef b/deployment/old/windows/dialogs/setuptype.nsddef similarity index 100% rename from deployment/windows/dialogs/setuptype.nsddef rename to deployment/old/windows/dialogs/setuptype.nsddef diff --git a/deployment/windows/dialogs/setuptype.nsdinc b/deployment/old/windows/dialogs/setuptype.nsdinc similarity index 100% rename from deployment/windows/dialogs/setuptype.nsdinc rename to deployment/old/windows/dialogs/setuptype.nsdinc diff --git a/deployment/windows/helpers/ShowError.nsh b/deployment/old/windows/helpers/ShowError.nsh similarity index 100% rename from deployment/windows/helpers/ShowError.nsh rename to deployment/old/windows/helpers/ShowError.nsh diff --git a/deployment/windows/helpers/StrSlash.nsh b/deployment/old/windows/helpers/StrSlash.nsh similarity index 100% rename from deployment/windows/helpers/StrSlash.nsh rename to deployment/old/windows/helpers/StrSlash.nsh diff --git a/deployment/windows/jellyfin.nsi b/deployment/old/windows/jellyfin.nsi similarity index 100% rename from deployment/windows/jellyfin.nsi rename to deployment/old/windows/jellyfin.nsi diff --git a/deployment/windows/legacy/install-jellyfin.ps1 b/deployment/old/windows/legacy/install-jellyfin.ps1 similarity index 100% rename from deployment/windows/legacy/install-jellyfin.ps1 rename to deployment/old/windows/legacy/install-jellyfin.ps1 diff --git a/deployment/windows/legacy/install.bat b/deployment/old/windows/legacy/install.bat similarity index 100% rename from deployment/windows/legacy/install.bat rename to deployment/old/windows/legacy/install.bat From 8b620ed26addec0f42e2797e3e4d45fbd68b0f23 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 22 Mar 2020 16:01:33 -0400 Subject: [PATCH 020/517] Move Debian folder to root of repo --- debian/changelog | 59 ++++++++++++++++++++ debian/compat | 1 + debian/conf/jellyfin | 40 ++++++++++++++ debian/conf/jellyfin-sudoers | 37 +++++++++++++ debian/conf/jellyfin.service.conf | 7 +++ debian/conf/logging.json | 30 ++++++++++ debian/control | 31 +++++++++++ debian/copyright | 29 ++++++++++ debian/gbp.conf | 6 ++ debian/install | 6 ++ debian/jellyfin.init | 61 ++++++++++++++++++++ debian/jellyfin.service | 14 +++++ debian/jellyfin.upstart | 20 +++++++ debian/po/POTFILES.in | 1 + debian/po/templates.pot | 57 +++++++++++++++++++ debian/postinst | 92 +++++++++++++++++++++++++++++++ debian/postrm | 81 +++++++++++++++++++++++++++ debian/preinst | 78 ++++++++++++++++++++++++++ debian/prerm | 61 ++++++++++++++++++++ debian/rules | 66 ++++++++++++++++++++++ debian/source.lintian-overrides | 3 + debian/source/format | 1 + debian/source/options | 11 ++++ 23 files changed, 792 insertions(+) create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/conf/jellyfin create mode 100644 debian/conf/jellyfin-sudoers create mode 100644 debian/conf/jellyfin.service.conf create mode 100644 debian/conf/logging.json create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/gbp.conf create mode 100644 debian/install create mode 100644 debian/jellyfin.init create mode 100644 debian/jellyfin.service create mode 100644 debian/jellyfin.upstart create mode 100644 debian/po/POTFILES.in create mode 100644 debian/po/templates.pot create mode 100644 debian/postinst create mode 100644 debian/postrm create mode 100644 debian/preinst create mode 100644 debian/prerm create mode 100755 debian/rules create mode 100644 debian/source.lintian-overrides create mode 100644 debian/source/format create mode 100644 debian/source/options diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000000..51c4822370 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,59 @@ +jellyfin (10.5.0-1) unstable; urgency=medium + + * New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 + + -- Jellyfin Packaging Team Fri, 11 Oct 2019 20:12:38 -0400 + +jellyfin (10.4.0-1) unstable; urgency=medium + + * New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 + + -- Jellyfin Packaging Team Sat, 31 Aug 2019 21:38:56 -0400 + +jellyfin (10.3.7-1) unstable; urgency=medium + + * New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 + + -- Jellyfin Packaging Team Wed, 24 Jul 2019 10:48:28 -0400 + +jellyfin (10.3.6-1) unstable; urgency=medium + + * New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 + + -- Jellyfin Packaging Team Sat, 06 Jul 2019 13:34:19 -0400 + +jellyfin (10.3.5-1) unstable; urgency=medium + + * New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 + + -- Jellyfin Packaging Team Sun, 09 Jun 2019 21:47:35 -0400 + +jellyfin (10.3.4-1) unstable; urgency=medium + + * New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 + + -- Jellyfin Packaging Team Thu, 06 Jun 2019 22:45:31 -0400 + +jellyfin (10.3.3-1) unstable; urgency=medium + + * New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 + + -- Jellyfin Packaging Team Fri, 17 May 2019 23:12:08 -0400 + +jellyfin (10.3.2-1) unstable; urgency=medium + + * New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 + + -- Jellyfin Packaging Team Tue, 30 Apr 2019 20:18:44 -0400 + +jellyfin (10.3.1-1) unstable; urgency=medium + + * New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 + + -- Jellyfin Packaging Team Sat, 20 Apr 2019 14:24:07 -0400 + +jellyfin (10.3.0-1) unstable; urgency=medium + + * New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 + + -- Jellyfin Packaging Team Fri, 19 Apr 2019 14:24:29 -0400 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000000..45a4fb75db --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +8 diff --git a/debian/conf/jellyfin b/debian/conf/jellyfin new file mode 100644 index 0000000000..c6e595f15a --- /dev/null +++ b/debian/conf/jellyfin @@ -0,0 +1,40 @@ +# Jellyfin default configuration options +# This is a POSIX shell fragment + +# Use this file to override the default configurations; add additional +# options with JELLYFIN_ADD_OPTS. + +# Under systemd, use +# /etc/systemd/system/jellyfin.service.d/jellyfin.service.conf +# to override the user or this config file's location. + +# +# General options +# + +# Program directories +JELLYFIN_DATA_DIR="/var/lib/jellyfin" +JELLYFIN_CONFIG_DIR="/etc/jellyfin" +JELLYFIN_LOG_DIR="/var/log/jellyfin" +JELLYFIN_CACHE_DIR="/var/cache/jellyfin" + +# Restart script for in-app server control +JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh" + +# ffmpeg binary paths, overriding the system values +JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/lib/jellyfin-ffmpeg/ffmpeg" + +# [OPTIONAL] run Jellyfin as a headless service +#JELLYFIN_SERVICE_OPT="--service" + +# [OPTIONAL] run Jellyfin without the web app +#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" + +# +# SysV init/Upstart options +# + +# Application username +JELLYFIN_USER="jellyfin" +# Full application command +JELLYFIN_ARGS="$JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLFIN_NOWEBAPP_OPT" diff --git a/debian/conf/jellyfin-sudoers b/debian/conf/jellyfin-sudoers new file mode 100644 index 0000000000..b481ba4ad4 --- /dev/null +++ b/debian/conf/jellyfin-sudoers @@ -0,0 +1,37 @@ +#Allow jellyfin group to start, stop and restart itself +Cmnd_Alias RESTARTSERVER_SYSV = /sbin/service jellyfin restart, /usr/sbin/service jellyfin restart +Cmnd_Alias STARTSERVER_SYSV = /sbin/service jellyfin start, /usr/sbin/service jellyfin start +Cmnd_Alias STOPSERVER_SYSV = /sbin/service jellyfin stop, /usr/sbin/service jellyfin stop +Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin +Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin +Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin +Cmnd_Alias RESTARTSERVER_INITD = /etc/init.d/jellyfin restart +Cmnd_Alias STARTSERVER_INITD = /etc/init.d/jellyfin start +Cmnd_Alias STOPSERVER_INITD = /etc/init.d/jellyfin stop + + +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSV +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSV +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSV +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_INITD +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_INITD +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_INITD + +Defaults!RESTARTSERVER_SYSV !requiretty +Defaults!STARTSERVER_SYSV !requiretty +Defaults!STOPSERVER_SYSV !requiretty +Defaults!RESTARTSERVER_SYSTEMD !requiretty +Defaults!STARTSERVER_SYSTEMD !requiretty +Defaults!STOPSERVER_SYSTEMD !requiretty +Defaults!RESTARTSERVER_INITD !requiretty +Defaults!STARTSERVER_INITD !requiretty +Defaults!STOPSERVER_INITD !requiretty + +#Allow the server to mount iso images +jellyfin ALL=(ALL) NOPASSWD: /bin/mount +jellyfin ALL=(ALL) NOPASSWD: /bin/umount + +Defaults:jellyfin !requiretty diff --git a/debian/conf/jellyfin.service.conf b/debian/conf/jellyfin.service.conf new file mode 100644 index 0000000000..1b69dd74ef --- /dev/null +++ b/debian/conf/jellyfin.service.conf @@ -0,0 +1,7 @@ +# Jellyfin systemd configuration options + +# Use this file to override the user or environment file location. + +[Service] +#User = jellyfin +#EnvironmentFile = /etc/default/jellyfin diff --git a/debian/conf/logging.json b/debian/conf/logging.json new file mode 100644 index 0000000000..f32b2089eb --- /dev/null +++ b/debian/conf/logging.json @@ -0,0 +1,30 @@ +{ + "Serilog": { + "MinimumLevel": "Information", + "WriteTo": [ + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Async", + "Args": { + "configure": [ + { + "Name": "File", + "Args": { + "path": "%JELLYFIN_LOG_DIR%//jellyfin.log", + "fileSizeLimitBytes": 10485700, + "rollOnFileSizeLimit": true, + "retainedFileCountLimit": 10, + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] {Message}{NewLine}{Exception}" + } + } + ] + } + } + ] + } +} diff --git a/debian/control b/debian/control new file mode 100644 index 0000000000..13fd3ecabb --- /dev/null +++ b/debian/control @@ -0,0 +1,31 @@ +Source: jellyfin +Section: misc +Priority: optional +Maintainer: Jellyfin Team +Build-Depends: debhelper (>= 9), + dotnet-sdk-3.1, + libc6-dev, + libcurl4-openssl-dev, + libfontconfig1-dev, + libfreetype6-dev, + libssl-dev, + wget, + npm | nodejs +Standards-Version: 3.9.4 +Homepage: https://jellyfin.media/ +Vcs-Git: https://github.org/jellyfin/jellyfin.git +Vcs-Browser: https://github.org/jellyfin/jellyfin + +Package: jellyfin +Replaces: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server +Breaks: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server +Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server +Architecture: any +Depends: at, + libsqlite3-0, + jellyfin-ffmpeg, + libfontconfig1, + libfreetype6, + libssl1.1 +Description: Jellyfin is a home media server. + It is built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono. It features a REST-based api with built-in documentation to facilitate client development. We also have client libraries for our api to enable rapid development. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000000..0d7a2a6007 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,29 @@ +Format: http://dep.debian.net/deps/dep5 +Upstream-Name: jellyfin +Source: https://github.com/jellyfin/jellyfin + +Files: * +Copyright: 2018 Jellyfin Team +License: GPL-2.0+ + +Files: debian/* +Copyright: 2018 Joshua Boniface +Copyright: 2014 Carlos Hernandez +License: GPL-2.0+ + +License: GPL-2.0+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/debian/gbp.conf b/debian/gbp.conf new file mode 100644 index 0000000000..60b3d28723 --- /dev/null +++ b/debian/gbp.conf @@ -0,0 +1,6 @@ +[DEFAULT] +pristine-tar = False +cleaner = fakeroot debian/rules clean + +[import-orig] +filter = [ ".git*", ".hg*", ".vs*", ".vscode*" ] diff --git a/debian/install b/debian/install new file mode 100644 index 0000000000..994322d141 --- /dev/null +++ b/debian/install @@ -0,0 +1,6 @@ +usr/lib/jellyfin usr/lib/ +debian/conf/jellyfin etc/default/ +debian/conf/logging.json etc/jellyfin/ +debian/conf/jellyfin.service.conf etc/systemd/system/jellyfin.service.d/ +debian/conf/jellyfin-sudoers etc/sudoers.d/ +debian/bin/restart.sh usr/lib/jellyfin/ diff --git a/debian/jellyfin.init b/debian/jellyfin.init new file mode 100644 index 0000000000..7f5642bac1 --- /dev/null +++ b/debian/jellyfin.init @@ -0,0 +1,61 @@ +### BEGIN INIT INFO +# Provides: Jellyfin Media Server +# Required-Start: $local_fs $network +# Required-Stop: $local_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Jellyfin Media Server +# Description: Runs Jellyfin Server +### END INIT INFO + +set -e + +# Carry out specific functions when asked to by the system + +if test -f /etc/default/jellyfin; then + . /etc/default/jellyfin +fi + +. /lib/lsb/init-functions + +PIDFILE="/run/jellyfin.pid" + +case "$1" in + start) + log_daemon_msg "Starting Jellyfin Media Server" "jellyfin" || true + + if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then + log_end_msg 0 || true + else + log_end_msg 1 || true + fi + ;; + + stop) + log_daemon_msg "Stopping Jellyfin Media Server" "jellyfin" || true + if start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --remove-pidfile; then + log_end_msg 0 || true + else + log_end_msg 1 || true + fi + ;; + + restart) + log_daemon_msg "Restarting Jellyfin Media Server" "jellyfin" || true + start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE --remove-pidfile + if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then + log_end_msg 0 || true + else + log_end_msg 1 || true + fi + ;; + + status) + status_of_proc -p $PIDFILE /usr/bin/jellyfin jellyfin && exit 0 || exit $? + ;; + + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac diff --git a/debian/jellyfin.service b/debian/jellyfin.service new file mode 100644 index 0000000000..1305e238b0 --- /dev/null +++ b/debian/jellyfin.service @@ -0,0 +1,14 @@ +[Unit] +Description = Jellyfin Media Server +After = network.target + +[Service] +Type = simple +EnvironmentFile = /etc/default/jellyfin +User = jellyfin +ExecStart = /usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} +Restart = on-failure +TimeoutSec = 15 + +[Install] +WantedBy = multi-user.target diff --git a/debian/jellyfin.upstart b/debian/jellyfin.upstart new file mode 100644 index 0000000000..ef5bc9bcaf --- /dev/null +++ b/debian/jellyfin.upstart @@ -0,0 +1,20 @@ +description "jellyfin daemon" + +start on (local-filesystems and net-device-up IFACE!=lo) +stop on runlevel [!2345] + +console log +respawn +respawn limit 10 5 + +kill timeout 20 + +script + set -x + echo "Starting $UPSTART_JOB" + + # Log file + logger -t "$0" "DEBUG: `set`" + . /etc/default/jellyfin + exec su -u $JELLYFIN_USER -c /usr/bin/jellyfin $JELLYFIN_ARGS +end script diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in new file mode 100644 index 0000000000..cef83a3407 --- /dev/null +++ b/debian/po/POTFILES.in @@ -0,0 +1 @@ +[type: gettext/rfc822deb] templates diff --git a/debian/po/templates.pot b/debian/po/templates.pot new file mode 100644 index 0000000000..2cdcae4173 --- /dev/null +++ b/debian/po/templates.pot @@ -0,0 +1,57 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: jellyfin-server\n" +"Report-Msgid-Bugs-To: jellyfin-server@packages.debian.org\n" +"POT-Creation-Date: 2015-06-12 20:51-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../templates:1001 +msgid "Jellyfin permission info:" +msgstr "" + +#. Type: note +#. Description +#: ../templates:1001 +msgid "" +"Jellyfin by default runs under a user named \"jellyfin\". Please ensure that the " +"user jellyfin has read and write access to any folders you wish to add to your " +"library. Otherwise please run jellyfin under a different user." +msgstr "" + +#. Type: string +#. Description +#: ../templates:2001 +msgid "Username to run Jellyfin as:" +msgstr "" + +#. Type: string +#. Description +#: ../templates:2001 +msgid "The user that jellyfin will run as." +msgstr "" + +#. Type: note +#. Description +#: ../templates:3001 +msgid "Jellyfin still running" +msgstr "" + +#. Type: note +#. Description +#: ../templates:3001 +msgid "Jellyfin is currently running. Please close it and try again." +msgstr "" diff --git a/debian/postinst b/debian/postinst new file mode 100644 index 0000000000..860222e051 --- /dev/null +++ b/debian/postinst @@ -0,0 +1,92 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +case "$1" in + configure) + # create jellyfin group if it does not exist + if [[ -z "$(getent group jellyfin)" ]]; then + addgroup --quiet --system jellyfin > /dev/null 2>&1 + fi + # create jellyfin user if it does not exist + if [[ -z "$(getent passwd jellyfin)" ]]; then + adduser --system --ingroup jellyfin --shell /bin/false jellyfin --no-create-home --home ${PROGRAMDATA} \ + --gecos "Jellyfin default user" > /dev/null 2>&1 + fi + # ensure $PROGRAMDATA exists + if [[ ! -d $PROGRAMDATA ]]; then + mkdir $PROGRAMDATA + fi + # ensure $CONFIGDATA exists + if [[ ! -d $CONFIGDATA ]]; then + mkdir $CONFIGDATA + fi + # ensure $LOGDATA exists + if [[ ! -d $LOGDATA ]]; then + mkdir $LOGDATA + fi + # ensure $CACHEDATA exists + if [[ ! -d $CACHEDATA ]]; then + mkdir $CACHEDATA + fi + # Ensure permissions are correct on all config directories + chown -R jellyfin $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA + chgrp adm $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA + chmod 0750 $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA + + chmod +x /usr/lib/jellyfin/restart.sh > /dev/null 2>&1 || true + + # Install jellyfin symlink into /usr/bin + ln -sf /usr/lib/jellyfin/bin/jellyfin /usr/bin/jellyfin + + ;; + abort-upgrade|abort-remove|abort-deconfigure) + ;; + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER + +if [[ -x "/usr/bin/deb-systemd-helper" ]]; then + # Manual init script handling + deb-systemd-helper unmask jellyfin.service >/dev/null || true + # was-enabled defaults to true, so new installations run enable. + if deb-systemd-helper --quiet was-enabled jellyfin.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable jellyfin.service >/dev/null || true + else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state jellyfin.service >/dev/null || true + fi +fi + +# End automatically added section +# Automatically added by dh_installinit +if [[ "$1" == "configure" ]] || [[ "$1" == "abort-upgrade" ]]; then + if [[ -d "/run/systemd/systemd" ]]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start jellyfin >/dev/null || true + elif [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.conf" ]]; then + update-rc.d jellyfin defaults >/dev/null + invoke-rc.d jellyfin start || exit $? + fi +fi +exit 0 diff --git a/debian/postrm b/debian/postrm new file mode 100644 index 0000000000..1d00a984ec --- /dev/null +++ b/debian/postrm @@ -0,0 +1,81 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [[ -d /run/systemd/system ]] ; then + systemctl --system daemon-reload >/dev/null || true +fi + +case "$1" in + purge) + echo PURGE | debconf-communicate $NAME > /dev/null 2>&1 || true + + if [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.connf" ]]; then + update-rc.d jellyfin remove >/dev/null 2>&1 || true + fi + + if [[ -x "/usr/bin/deb-systemd-helper" ]]; then + deb-systemd-helper purge jellyfin.service >/dev/null + deb-systemd-helper unmask jellyfin.service >/dev/null + fi + + # Remove user and group + userdel jellyfin > /dev/null 2>&1 || true + delgroup --quiet jellyfin > /dev/null 2>&1 || true + # Remove config dir + if [[ -d $CONFIGDATA ]]; then + rm -rf $CONFIGDATA + fi + # Remove log dir + if [[ -d $LOGDATA ]]; then + rm -rf $LOGDATA + fi + # Remove cache dir + if [[ -d $CACHEDATA ]]; then + rm -rf $CACHEDATA + fi + # Remove program data dir + if [[ -d $PROGRAMDATA ]]; then + rm -rf $PROGRAMDATA + fi + # Remove binary symlink + [[ -f /usr/bin/jellyfin ]] && rm /usr/bin/jellyfin + # Remove sudoers config + [[ -f /etc/sudoers.d/jellyfin-sudoers ]] && rm /etc/sudoers.d/jellyfin-sudoers + # Remove anything at the default locations; catches situations where the user moved the defaults + [[ -e /etc/jellyfin ]] && rm -rf /etc/jellyfin + [[ -e /var/log/jellyfin ]] && rm -rf /var/log/jellyfin + [[ -e /var/cache/jellyfin ]] && rm -rf /var/cache/jellyfin + [[ -e /var/lib/jellyfin ]] && rm -rf /var/lib/jellyfin + ;; + remove) + if [[ -x "/usr/bin/deb-systemd-helper" ]]; then + deb-systemd-helper mask jellyfin.service >/dev/null + fi + ;; + upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/debian/preinst b/debian/preinst new file mode 100644 index 0000000000..2713fb9b80 --- /dev/null +++ b/debian/preinst @@ -0,0 +1,78 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [[ -d /run/systemd/system ]] ; then + systemctl --system daemon-reload >/dev/null || true +fi + +case "$1" in + install|upgrade) + # try graceful termination; + if [[ -d /run/systemd/system ]]; then + deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true + elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then + invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true + fi + # try and figure out if jellyfin is running + PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) + [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) + # if its running, let's stop it + if [[ -n "$JELLYFIN_PID" ]]; then + echo "Stopping Jellyfin!" + # if jellyfin is still running, kill it + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + CPIDS=$(pgrep -P $JELLYFIN_PID) + sleep 2 && kill -KILL $CPIDS + kill -TERM $CPIDS > /dev/null 2>&1 + fi + sleep 1 + # if it's still running, show error + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + echo "Could not successfully stop JellyfinServer, please do so before uninstalling." + exit 1 + else + [[ -f $PIDFILE ]] && rm $PIDFILE + fi + fi + + # Clean up old Emby cruft that can break the user's system + [[ -f /etc/sudoers.d/emby ]] && rm -f /etc/sudoers.d/emby + + # If we have existing config, log, or cache dirs in /var/lib/jellyfin, move them into the right place + if [[ -d $PROGRAMDATA/config ]]; then + mv $PROGRAMDATA/config $CONFIGDATA + fi + if [[ -d $PROGRAMDATA/logs ]]; then + mv $PROGRAMDATA/logs $LOGDATA + fi + if [[ -d $PROGRAMDATA/logs ]]; then + mv $PROGRAMDATA/cache $CACHEDATA + fi + + ;; + abort-upgrade) + ;; + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac +#DEBHELPER# + +exit 0 diff --git a/debian/prerm b/debian/prerm new file mode 100644 index 0000000000..e965cb7d71 --- /dev/null +++ b/debian/prerm @@ -0,0 +1,61 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +case "$1" in + remove|upgrade|deconfigure) + echo "Stopping Jellyfin!" + # try graceful termination; + if [[ -d /run/systemd/system ]]; then + deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true + elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then + invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true + fi + # Ensure that it is shutdown + PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) + [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) + # if its running, let's stop it + if [[ -n "$JELLYFIN_PID" ]]; then + # if jellyfin is still running, kill it + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + CPIDS=$(pgrep -P $JELLYFIN_PID) + sleep 2 && kill -KILL $CPIDS + kill -TERM $CPIDS > /dev/null 2>&1 + fi + sleep 1 + # if it's still running, show error + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + echo "Could not successfully stop Jellyfin, please do so before uninstalling." + exit 1 + else + [[ -f $PIDFILE ]] && rm $PIDFILE + fi + fi + if [[ -f /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so ]]; then + rm /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so + fi + ;; + failed-upgrade) + ;; + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000000..c2d57dfb22 --- /dev/null +++ b/debian/rules @@ -0,0 +1,66 @@ +#! /usr/bin/make -f +CONFIG := Release +TERM := xterm +SHELL := /bin/bash +WEB_TARGET := $(CURDIR)/MediaBrowser.WebDashboard/jellyfin-web +WEB_VERSION := $(shell sed -n -e 's/^version: "\(.*\)"/\1/p' $(CURDIR)/build.yaml) + +HOST_ARCH := $(shell arch) +BUILD_ARCH := ${DEB_HOST_MULTIARCH} +ifeq ($(HOST_ARCH),x86_64) + # Building AMD64 + DOTNETRUNTIME := debian-x64 + ifeq ($(BUILD_ARCH),arm-linux-gnueabihf) + # Cross-building ARM on AMD64 + DOTNETRUNTIME := debian-arm + endif + ifeq ($(BUILD_ARCH),aarch64-linux-gnu) + # Cross-building ARM on AMD64 + DOTNETRUNTIME := debian-arm64 + endif +endif +ifeq ($(HOST_ARCH),armv7l) + # Building ARM + DOTNETRUNTIME := debian-arm +endif +ifeq ($(HOST_ARCH),arm64) + # Building ARM + DOTNETRUNTIME := debian-arm64 +endif + +export DH_VERBOSE=1 +export DOTNET_CLI_TELEMETRY_OPTOUT=1 + +%: + dh $@ + +# disable "make check" +override_dh_auto_test: + +# disable stripping debugging symbols +override_dh_clistrip: + +override_dh_auto_build: + echo $(WEB_VERSION) + # Clone down and build Web frontend + mkdir -p $(WEB_TARGET) + wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/v$(WEB_VERSION).tar.gz || wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/master.tar.gz + mkdir -p $(CURDIR)/web + tar -xzf web-src.tgz -C $(CURDIR)/web/ --strip 1 + cd $(CURDIR)/web/ && npm install yarn + cd $(CURDIR)/web/ && node_modules/yarn/bin/yarn install + mv $(CURDIR)/web/dist/* $(WEB_TARGET)/ + # Build the application + dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) \ + "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server + +override_dh_auto_clean: + dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true + rm -f '$(CURDIR)/web-src.tgz' + rm -rf '$(CURDIR)/usr' + rm -rf '$(CURDIR)/web' + rm -rf '$(WEB_TARGET)' + +# Force the service name to jellyfin even if we're building jellyfin-nightly +override_dh_installinit: + dh_installinit --name=jellyfin diff --git a/debian/source.lintian-overrides b/debian/source.lintian-overrides new file mode 100644 index 0000000000..aeb332f13a --- /dev/null +++ b/debian/source.lintian-overrides @@ -0,0 +1,3 @@ +# This is an override for the following lintian errors: +jellyfin source: license-problem-md5sum-non-free-file Emby.Drawing/ImageMagick/fonts/webdings.ttf* +jellyfin source: source-is-missing diff --git a/debian/source/format b/debian/source/format new file mode 100644 index 0000000000..d3827e75a5 --- /dev/null +++ b/debian/source/format @@ -0,0 +1 @@ +1.0 diff --git a/debian/source/options b/debian/source/options new file mode 100644 index 0000000000..17b5373d5e --- /dev/null +++ b/debian/source/options @@ -0,0 +1,11 @@ +tar-ignore='.git*' +tar-ignore='**/.git' +tar-ignore='**/.hg' +tar-ignore='**/.vs' +tar-ignore='**/.vscode' +tar-ignore='deployment' +tar-ignore='**/bin' +tar-ignore='**/obj' +tar-ignore='**/.nuget' +tar-ignore='*.deb' +tar-ignore='ThirdParty' From f9cecfc0fb0cbd7a75b8aace84f094a46824b705 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 22 Mar 2020 16:01:47 -0400 Subject: [PATCH 021/517] Add new build.sh script and symlink --- build | 1 + build.sh | 106 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 120000 build create mode 100755 build.sh diff --git a/build b/build new file mode 120000 index 0000000000..c07a74de4f --- /dev/null +++ b/build @@ -0,0 +1 @@ +build.sh \ No newline at end of file diff --git a/build.sh b/build.sh new file mode 100755 index 0000000000..b61126e11f --- /dev/null +++ b/build.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash + +# build.sh - Build Jellyfin binary packages +# Part of the Jellyfin Project + +set -o errexit +set -o pipefail + +usage() { + echo -e "build.sh - Build Jellyfin binary packages" + echo -e "Usage:" + echo -e " $0 -t/--type -p/--platform [-k/--keep-artifacts] [-l/--list-platforms]" + echo -e "Notes:" + echo -e " * BUILD_TYPE can be one of: [native, docker] and must be specified" + echo -e " * native: Build using the build script in the host OS" + echo -e " * docker: Build using the build script in a standardized Docker container" + echo -e " * PLATFORM can be any platform shown by -l/--list-platforms and must be specified" + echo -e " * If -k/--keep-artifacts is specified, transient artifacts (e.g. Docker containers) will be" + echo -e " retained after the build is finished" + echo -e " * If -l/--list-platforms is specified, all other arguments are ignored; the script will print" + echo -e " the list of supported platforms and exit" +} + +list_platforms() { + declare -a platforms + platforms=( + $( find deployment -maxdepth 1 -mindepth 1 -type f -name "build.*" | awk -F'.' '{ $1=""; print $2 "." $3 }' ) + ) + echo -e "Valid platforms:" + echo + for platform in ${platforms[@]}; do + echo -e "* ${platform} : $( grep '^#=' deployment/build.${platform} | sed 's/^#= //' )" + done +} + +do_build_native() { + export IS_DOCKER=NO + deployment/build.${PLATFORM} +} + +do_build_docker() { + if [[ ! -f deployment/Dockerfile.${PLATFORM} ]]; then + echo "Missing Dockerfile for platform ${PLATFORM}" + exit 1 + fi + if [[ ${KEEP_ARTIFACTS} == YES ]]; then + docker_args="" + else + docker_args="--rm" + fi + + docker build . -t "jellyfin-builder.${PLATFORM}" -f deployment/Dockerfile.${PLATFORM} + mkdir -p ${ARTIFACT_DIR} + docker run $docker_args -v "${ARTIFACT_DIR}:/dist" "jellyfin-builder.${PLATFORM}" +} + +while [[ $# -gt 0 ]]; do + key="$1" + case $key in + -t|--type) + BUILD_TYPE="$2" + shift # past argument + shift # past value + ;; + -p|--platform) + PLATFORM="$2" + shift # past argument + shift # past value + ;; + -k|--keep-artifacts) + KEEP_ARTIFACTS=YES + shift # past argument + ;; + -l|--list-platforms) + list_platforms + exit 0 + ;; + -h|--help) + usage + exit 0 + ;; + *) # unknown option + echo "Unknown option $1" + usage + exit 1 + ;; + esac +done + +if [[ -z ${BUILD_TYPE} || -z ${PLATFORM} ]]; then + usage + exit 1 +fi + +export SOURCE_DIR="$( pwd )" +export ARTIFACT_DIR="${SOURCE_DIR}/../bin/${PLATFORM}" + +# Determine build type +case ${BUILD_TYPE} in + native) + do_build_native + ;; + docker) + do_build_docker + ;; +esac From 3571afece104e39c676cfdb53df9392c225380d0 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 22 Mar 2020 16:02:35 -0400 Subject: [PATCH 022/517] Ignore web artifacts --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 42243f01a8..17cf4a6277 100644 --- a/.gitignore +++ b/.gitignore @@ -271,3 +271,8 @@ dist # BenchmarkDotNet artifacts BenchmarkDotNet.Artifacts + +# Ignore web artifacts from native builds +web/ +web-src.* +MediaBrowser.WebDashboard/jellyfin-web/ From ba55ee4986fa871390e211c56fdec1b024ff617e Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 22 Mar 2020 16:03:14 -0400 Subject: [PATCH 023/517] Add first proof-of-concept deployment setup --- deployment/Dockerfile.debian.amd64 | 34 ++++++++++++++++++++++++++++++ deployment/build.debian.amd64 | 26 +++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 deployment/Dockerfile.debian.amd64 create mode 100755 deployment/build.debian.amd64 diff --git a/deployment/Dockerfile.debian.amd64 b/deployment/Dockerfile.debian.amd64 new file mode 100644 index 0000000000..eb29402194 --- /dev/null +++ b/deployment/Dockerfile.debian.amd64 @@ -0,0 +1,34 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.amd64 /build.sh + +# Create the source dir +RUN mkdir -p ${SOURCE_DIR} + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/build.debian.amd64 b/deployment/build.debian.amd64 new file mode 100755 index 0000000000..89f8445d80 --- /dev/null +++ b/deployment/build.debian.amd64 @@ -0,0 +1,26 @@ +#!/bin/bash + +#= Debian 9+ amd64 .deb + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +if [[ ${IS_DOCKER} == YES ]]; then + # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + sed -i '/dotnet-sdk-3.1,/d' debian/control +fi + +# Build DEB +dpkg-buildpackage -us -uc --pre-clean --post-clean + +mkdir -p ${ARTIFACT_DIR}/ +mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd From 93d1256a4c80c071b0c14e066c13bb9720b63dc9 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 14:46:16 -0400 Subject: [PATCH 024/517] Remove web building, rename, bump version --- debian/changelog | 6 ++++++ debian/control | 9 ++++----- debian/rules | 15 --------------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/debian/changelog b/debian/changelog index 51c4822370..35fb659571 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +jellyfin-server (10.6.0-1) unstable; urgency=medium + + * Forthcoming stable release + + -- Jellyfin Packaging Team Mon, 23 Mar 2020 14:46:05 -0400 + jellyfin (10.5.0-1) unstable; urgency=medium * New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 diff --git a/debian/control b/debian/control index 13fd3ecabb..f473dc41d2 100644 --- a/debian/control +++ b/debian/control @@ -1,4 +1,4 @@ -Source: jellyfin +Source: jellyfin-server Section: misc Priority: optional Maintainer: Jellyfin Team @@ -8,15 +8,13 @@ Build-Depends: debhelper (>= 9), libcurl4-openssl-dev, libfontconfig1-dev, libfreetype6-dev, - libssl-dev, - wget, - npm | nodejs + libssl-dev Standards-Version: 3.9.4 Homepage: https://jellyfin.media/ Vcs-Git: https://github.org/jellyfin/jellyfin.git Vcs-Browser: https://github.org/jellyfin/jellyfin -Package: jellyfin +Package: jellyfin-server Replaces: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server Breaks: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server @@ -27,5 +25,6 @@ Depends: at, libfontconfig1, libfreetype6, libssl1.1 +Recommends: jellyfin-web Description: Jellyfin is a home media server. It is built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono. It features a REST-based api with built-in documentation to facilitate client development. We also have client libraries for our api to enable rapid development. diff --git a/debian/rules b/debian/rules index c2d57dfb22..2a5d41a696 100755 --- a/debian/rules +++ b/debian/rules @@ -2,8 +2,6 @@ CONFIG := Release TERM := xterm SHELL := /bin/bash -WEB_TARGET := $(CURDIR)/MediaBrowser.WebDashboard/jellyfin-web -WEB_VERSION := $(shell sed -n -e 's/^version: "\(.*\)"/\1/p' $(CURDIR)/build.yaml) HOST_ARCH := $(shell arch) BUILD_ARCH := ${DEB_HOST_MULTIARCH} @@ -41,25 +39,12 @@ override_dh_auto_test: override_dh_clistrip: override_dh_auto_build: - echo $(WEB_VERSION) - # Clone down and build Web frontend - mkdir -p $(WEB_TARGET) - wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/v$(WEB_VERSION).tar.gz || wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/master.tar.gz - mkdir -p $(CURDIR)/web - tar -xzf web-src.tgz -C $(CURDIR)/web/ --strip 1 - cd $(CURDIR)/web/ && npm install yarn - cd $(CURDIR)/web/ && node_modules/yarn/bin/yarn install - mv $(CURDIR)/web/dist/* $(WEB_TARGET)/ - # Build the application dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) \ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server override_dh_auto_clean: dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true - rm -f '$(CURDIR)/web-src.tgz' rm -rf '$(CURDIR)/usr' - rm -rf '$(CURDIR)/web' - rm -rf '$(WEB_TARGET)' # Force the service name to jellyfin even if we're building jellyfin-nightly override_dh_installinit: From c61e95d11757656f9a71ec4b6d410c4c5936f516 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 14:49:55 -0400 Subject: [PATCH 025/517] Only support Docker builds on amd64 --- build.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build.sh b/build.sh index b61126e11f..f318a0b1f6 100755 --- a/build.sh +++ b/build.sh @@ -39,6 +39,10 @@ do_build_native() { } do_build_docker() { + if ! dpkg --print-architecture | grep -q 'amd64'; then + echo "Docker-based builds only support amd64-based cross-building; use a native build instead" + exit 1 + fi if [[ ! -f deployment/Dockerfile.${PLATFORM} ]]; then echo "Missing Dockerfile for platform ${PLATFORM}" exit 1 From 163cf223aa1b0b89c159b4d23c9ee9d888b96416 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:00:41 -0400 Subject: [PATCH 026/517] Only support cross-building with Docker --- build.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index f318a0b1f6..238871c168 100755 --- a/build.sh +++ b/build.sh @@ -34,13 +34,17 @@ list_platforms() { } do_build_native() { + if [[ $( dpkg --print-architecture | head -1 ) != "${PLATFORM##*.}" ]]; then + echo "Cross-building is not supported for native builds, use 'docker' builds on amd64 for cross-building." + exit 1 + fi export IS_DOCKER=NO deployment/build.${PLATFORM} } do_build_docker() { if ! dpkg --print-architecture | grep -q 'amd64'; then - echo "Docker-based builds only support amd64-based cross-building; use a native build instead" + echo "Docker-based builds only support amd64-based cross-building; use a 'native' build instead." exit 1 fi if [[ ! -f deployment/Dockerfile.${PLATFORM} ]]; then From 9c378866e4bcc26315c3618cd7d91c96f90630d5 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:02:54 -0400 Subject: [PATCH 027/517] Add arm64 and armhf builds --- deployment/Dockerfile.debian.arm64 | 42 ++++++++++++++++++++++++++++++ deployment/Dockerfile.debian.armhf | 42 ++++++++++++++++++++++++++++++ deployment/build.debian.arm64 | 27 +++++++++++++++++++ deployment/build.debian.armhf | 27 +++++++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 deployment/Dockerfile.debian.arm64 create mode 100644 deployment/Dockerfile.debian.armhf create mode 100755 deployment/build.debian.arm64 create mode 100755 deployment/build.debian.armhf diff --git a/deployment/Dockerfile.debian.arm64 b/deployment/Dockerfile.debian.arm64 new file mode 100644 index 0000000000..6e7e80d701 --- /dev/null +++ b/deployment/Dockerfile.debian.arm64 @@ -0,0 +1,42 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Prepare the cross-toolchain +RUN dpkg --add-architecture arm64 \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="arm64" cross-gcc-gensource 8 \ + && cd cross-gcc-packages-amd64/cross-gcc-8-arm64 \ + && apt-get install -y gcc-8-source libstdc++-8-dev-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 libssl-dev:arm64 liblttng-ust0:arm64 libstdc++-8-dev:arm64 + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.arm64 /build.sh + +# Create the source dir +RUN mkdir -p ${SOURCE_DIR} + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf new file mode 100644 index 0000000000..6e2e3a40cb --- /dev/null +++ b/deployment/Dockerfile.debian.armhf @@ -0,0 +1,42 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Prepare the cross-toolchain +RUN dpkg --add-architecture armhf \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="armhf" cross-gcc-gensource 8 \ + && cd cross-gcc-packages-amd64/cross-gcc-8-armhf \ + && apt-get install -y gcc-8-source libstdc++-8-dev-armhf-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf liblttng-ust0:armhf libstdc++-8-dev:armhf + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh + +# Create the source dir +RUN mkdir -p ${SOURCE_DIR} + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/build.debian.arm64 b/deployment/build.debian.arm64 new file mode 100755 index 0000000000..3525ae471c --- /dev/null +++ b/deployment/build.debian.arm64 @@ -0,0 +1,27 @@ +#!/bin/bash + +#= Debian 9+ arm64 .deb + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +if [[ ${IS_DOCKER} == YES ]]; then + # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + sed -i '/dotnet-sdk-3.1,/d' debian/control +fi + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -a arm64 --pre-clean --post-clean + +mkdir -p ${ARTIFACT_DIR}/ +mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/deployment/build.debian.armhf b/deployment/build.debian.armhf new file mode 100755 index 0000000000..45730eebef --- /dev/null +++ b/deployment/build.debian.armhf @@ -0,0 +1,27 @@ +#!/bin/bash + +#= Debian 9+ arm64 .deb + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +if [[ ${IS_DOCKER} == YES ]]; then + # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + sed -i '/dotnet-sdk-3.1,/d' debian/control +fi + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -a armhf --pre-clean --post-clean + +mkdir -p ${ARTIFACT_DIR}/ +mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd From 0365adb8233352c3261d669aeb83b8503100796b Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:24:13 -0400 Subject: [PATCH 028/517] Fix deps for armhf --- deployment/Dockerfile.debian.armhf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf index 6e2e3a40cb..8ebe1830ab 100644 --- a/deployment/Dockerfile.debian.armhf +++ b/deployment/Dockerfile.debian.armhf @@ -27,7 +27,7 @@ RUN dpkg --add-architecture armhf \ && apt-get install -y cross-gcc-dev \ && TARGET_LIST="armhf" cross-gcc-gensource 8 \ && cd cross-gcc-packages-amd64/cross-gcc-8-armhf \ - && apt-get install -y gcc-8-source libstdc++-8-dev-armhf-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf liblttng-ust0:armhf libstdc++-8-dev:armhf + && apt-get install -y gcc-8-source libstdc++-8-dev-armhf-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip binutils-arm-linux-gnueabihf libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf liblttng-ust0:armhf libstdc++-8-dev:armhf # Link to build script RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh From c4a29e537cf7f74d592a4b230627876f0bf0de37 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:28:57 -0400 Subject: [PATCH 029/517] Remove NPM install from Dockerfiles --- deployment/Dockerfile.debian.amd64 | 2 +- deployment/Dockerfile.debian.arm64 | 2 +- deployment/Dockerfile.debian.armhf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deployment/Dockerfile.debian.amd64 b/deployment/Dockerfile.debian.amd64 index eb29402194..47c13fa712 100644 --- a/deployment/Dockerfile.debian.amd64 +++ b/deployment/Dockerfile.debian.amd64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.debian.arm64 b/deployment/Dockerfile.debian.arm64 index 6e7e80d701..7b792d7e16 100644 --- a/deployment/Dockerfile.debian.arm64 +++ b/deployment/Dockerfile.debian.arm64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf index 8ebe1830ab..d633d316a2 100644 --- a/deployment/Dockerfile.debian.armhf +++ b/deployment/Dockerfile.debian.armhf @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current From f72c5b7a1d4db9b16f3b15cebe12bbca110bf7ef Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:40:19 -0400 Subject: [PATCH 030/517] Fix version output --- deployment/build.debian.amd64 | 2 +- deployment/build.debian.arm64 | 2 +- deployment/build.debian.armhf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deployment/build.debian.amd64 b/deployment/build.debian.amd64 index 89f8445d80..c43585161d 100755 --- a/deployment/build.debian.amd64 +++ b/deployment/build.debian.amd64 @@ -1,6 +1,6 @@ #!/bin/bash -#= Debian 9+ amd64 .deb +#= Debian 10+ amd64 .deb set -o errexit set -o xtrace diff --git a/deployment/build.debian.arm64 b/deployment/build.debian.arm64 index 3525ae471c..4225c2f9df 100755 --- a/deployment/build.debian.arm64 +++ b/deployment/build.debian.arm64 @@ -1,6 +1,6 @@ #!/bin/bash -#= Debian 9+ arm64 .deb +#= Debian 10+ arm64 .deb set -o errexit set -o xtrace diff --git a/deployment/build.debian.armhf b/deployment/build.debian.armhf index 45730eebef..f71a960410 100755 --- a/deployment/build.debian.armhf +++ b/deployment/build.debian.armhf @@ -1,6 +1,6 @@ #!/bin/bash -#= Debian 9+ arm64 .deb +#= Debian 10+ arm64 .deb set -o errexit set -o xtrace From 9ce2af2a6c20c061bb1317728262bad305d05f27 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:40:51 -0400 Subject: [PATCH 031/517] Don't limit to files (allow symlinks) --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 238871c168..f54ce04ce7 100755 --- a/build.sh +++ b/build.sh @@ -24,7 +24,7 @@ usage() { list_platforms() { declare -a platforms platforms=( - $( find deployment -maxdepth 1 -mindepth 1 -type f -name "build.*" | awk -F'.' '{ $1=""; print $2 "." $3 }' ) + $( find deployment -maxdepth 1 -mindepth 1 -name "build.*" | awk -F'.' '{ $1=""; print $2 "." $3 }' | sort ) ) echo -e "Valid platforms:" echo From 3e7a106a95a183ba4c7d1bf00d87e149463f0e23 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:40:59 -0400 Subject: [PATCH 032/517] Add Ubuntu configurations --- deployment/Dockerfile.ubuntu.amd64 | 34 +++++++++++++++++++ deployment/Dockerfile.ubuntu.arm64 | 53 ++++++++++++++++++++++++++++++ deployment/Dockerfile.ubuntu.armhf | 53 ++++++++++++++++++++++++++++++ deployment/build.ubuntu.amd64 | 26 +++++++++++++++ deployment/build.ubuntu.arm64 | 27 +++++++++++++++ deployment/build.ubuntu.armhf | 27 +++++++++++++++ 6 files changed, 220 insertions(+) create mode 100644 deployment/Dockerfile.ubuntu.amd64 create mode 100644 deployment/Dockerfile.ubuntu.arm64 create mode 100644 deployment/Dockerfile.ubuntu.armhf create mode 100755 deployment/build.ubuntu.amd64 create mode 100755 deployment/build.ubuntu.arm64 create mode 100755 deployment/build.ubuntu.armhf diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64 new file mode 100644 index 0000000000..e1b0c3975d --- /dev/null +++ b/deployment/Dockerfile.ubuntu.amd64 @@ -0,0 +1,34 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.amd64 /build.sh + +# Create the source dir +RUN mkdir -p ${SOURCE_DIR} + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 new file mode 100644 index 0000000000..98dfbf7dd6 --- /dev/null +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -0,0 +1,53 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=arm64 +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Prepare the cross-toolchain +RUN rm /etc/apt/sources.list \ + && export CODENAME="$( lsb_release -c -s )" \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && dpkg --add-architecture arm64 \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="arm64" cross-gcc-gensource 6 \ + && cd cross-gcc-packages-amd64/cross-gcc-6-arm64 \ + && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ + && apt-get install -y gcc-6-source libstdc++6-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 liblttng-ust0:arm64 libstdc++6:arm64 libssl-dev:arm64 + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.arm64 /build.sh + +# Create the source dir +RUN mkdir -p ${SOURCE_DIR} + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf new file mode 100644 index 0000000000..30cd861359 --- /dev/null +++ b/deployment/Dockerfile.ubuntu.armhf @@ -0,0 +1,53 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=armhf +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Prepare the cross-toolchain +RUN rm /etc/apt/sources.list \ + && export CODENAME="$( lsb_release -c -s )" \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && dpkg --add-architecture armhf \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="armhf" cross-gcc-gensource 6 \ + && cd cross-gcc-packages-amd64/cross-gcc-6-armhf \ + && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ + && apt-get install -y gcc-6-source libstdc++6-armhf-cross binutils-arm-linux-gnueabihf bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf liblttng-ust0:armhf libstdc++6:armhf libssl-dev:armhf + +# Link to build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh + +# Create the source dir +RUN mkdir -p ${SOURCE_DIR} + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/build.ubuntu.amd64 b/deployment/build.ubuntu.amd64 new file mode 100755 index 0000000000..e74db90c43 --- /dev/null +++ b/deployment/build.ubuntu.amd64 @@ -0,0 +1,26 @@ +#!/bin/bash + +#= Ubuntu 18.04+ amd64 .deb + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +if [[ ${IS_DOCKER} == YES ]]; then + # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + sed -i '/dotnet-sdk-3.1,/d' debian/control +fi + +# Build DEB +dpkg-buildpackage -us -uc --pre-clean --post-clean + +mkdir -p ${ARTIFACT_DIR}/ +mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/deployment/build.ubuntu.arm64 b/deployment/build.ubuntu.arm64 new file mode 100755 index 0000000000..1d91b303ad --- /dev/null +++ b/deployment/build.ubuntu.arm64 @@ -0,0 +1,27 @@ +#!/bin/bash + +#= Ubuntu 18.04+ arm64 .deb + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +if [[ ${IS_DOCKER} == YES ]]; then + # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + sed -i '/dotnet-sdk-3.1,/d' debian/control +fi + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -a arm64 --pre-clean --post-clean + +mkdir -p ${ARTIFACT_DIR}/ +mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/deployment/build.ubuntu.armhf b/deployment/build.ubuntu.armhf new file mode 100755 index 0000000000..efdc2b65b1 --- /dev/null +++ b/deployment/build.ubuntu.armhf @@ -0,0 +1,27 @@ +#!/bin/bash + +#= Ubuntu 18.04+ arm64 .deb + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +if [[ ${IS_DOCKER} == YES ]]; then + # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + sed -i '/dotnet-sdk-3.1,/d' debian/control +fi + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -a armhf --pre-clean --post-clean + +mkdir -p ${ARTIFACT_DIR}/ +mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd From 8b1a76a32e5c2d8677fc6bba62682cfc1af748e6 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 15:44:23 -0400 Subject: [PATCH 033/517] Mount the source volume rather than copy it Now that the build script cleans up both before and after building, this is a viable option and will significant reduce build times by promoting container reuse (with `-k`). --- build.sh | 4 ++-- deployment/Dockerfile.debian.amd64 | 5 +---- deployment/Dockerfile.debian.arm64 | 5 +---- deployment/Dockerfile.debian.armhf | 5 +---- deployment/Dockerfile.ubuntu.amd64 | 5 +---- deployment/Dockerfile.ubuntu.arm64 | 5 +---- deployment/Dockerfile.ubuntu.armhf | 5 +---- 7 files changed, 8 insertions(+), 26 deletions(-) diff --git a/build.sh b/build.sh index f54ce04ce7..5d3f8ec713 100755 --- a/build.sh +++ b/build.sh @@ -16,7 +16,7 @@ usage() { echo -e " * docker: Build using the build script in a standardized Docker container" echo -e " * PLATFORM can be any platform shown by -l/--list-platforms and must be specified" echo -e " * If -k/--keep-artifacts is specified, transient artifacts (e.g. Docker containers) will be" - echo -e " retained after the build is finished" + echo -e " retained after the build is finished; the source directory will still be cleaned" echo -e " * If -l/--list-platforms is specified, all other arguments are ignored; the script will print" echo -e " the list of supported platforms and exit" } @@ -59,7 +59,7 @@ do_build_docker() { docker build . -t "jellyfin-builder.${PLATFORM}" -f deployment/Dockerfile.${PLATFORM} mkdir -p ${ARTIFACT_DIR} - docker run $docker_args -v "${ARTIFACT_DIR}:/dist" "jellyfin-builder.${PLATFORM}" + docker run $docker_args -v "${SOURCE_DIR}:/jellyfin" -v "${ARTIFACT_DIR}:/dist" "jellyfin-builder.${PLATFORM}" } while [[ $# -gt 0 ]]; do diff --git a/deployment/Dockerfile.debian.amd64 b/deployment/Dockerfile.debian.amd64 index 47c13fa712..b5a0380489 100644 --- a/deployment/Dockerfile.debian.amd64 +++ b/deployment/Dockerfile.debian.amd64 @@ -24,11 +24,8 @@ RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4 # Link to build script RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.amd64 /build.sh -# Create the source dir -RUN mkdir -p ${SOURCE_DIR} +VOLUME ${SOURCE_DIR}/ VOLUME ${ARTIFACT_DIR}/ -COPY . ${SOURCE_DIR}/ - ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.debian.arm64 b/deployment/Dockerfile.debian.arm64 index 7b792d7e16..cfe562df33 100644 --- a/deployment/Dockerfile.debian.arm64 +++ b/deployment/Dockerfile.debian.arm64 @@ -32,11 +32,8 @@ RUN dpkg --add-architecture arm64 \ # Link to build script RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.arm64 /build.sh -# Create the source dir -RUN mkdir -p ${SOURCE_DIR} +VOLUME ${SOURCE_DIR}/ VOLUME ${ARTIFACT_DIR}/ -COPY . ${SOURCE_DIR}/ - ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf index d633d316a2..ea8c8c8e62 100644 --- a/deployment/Dockerfile.debian.armhf +++ b/deployment/Dockerfile.debian.armhf @@ -32,11 +32,8 @@ RUN dpkg --add-architecture armhf \ # Link to build script RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh -# Create the source dir -RUN mkdir -p ${SOURCE_DIR} +VOLUME ${SOURCE_DIR}/ VOLUME ${ARTIFACT_DIR}/ -COPY . ${SOURCE_DIR}/ - ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64 index e1b0c3975d..e61be4efcc 100644 --- a/deployment/Dockerfile.ubuntu.amd64 +++ b/deployment/Dockerfile.ubuntu.amd64 @@ -24,11 +24,8 @@ RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4 # Link to build script RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.amd64 /build.sh -# Create the source dir -RUN mkdir -p ${SOURCE_DIR} +VOLUME ${SOURCE_DIR}/ VOLUME ${ARTIFACT_DIR}/ -COPY . ${SOURCE_DIR}/ - ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 index 98dfbf7dd6..e34ef7edd1 100644 --- a/deployment/Dockerfile.ubuntu.arm64 +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -43,11 +43,8 @@ RUN rm /etc/apt/sources.list \ # Link to build script RUN ln -sf ${SOURCE_DIR}/deployment/build.ubuntu.arm64 /build.sh -# Create the source dir -RUN mkdir -p ${SOURCE_DIR} +VOLUME ${SOURCE_DIR}/ VOLUME ${ARTIFACT_DIR}/ -COPY . ${SOURCE_DIR}/ - ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf index 30cd861359..6f92c81ab1 100644 --- a/deployment/Dockerfile.ubuntu.armhf +++ b/deployment/Dockerfile.ubuntu.armhf @@ -43,11 +43,8 @@ RUN rm /etc/apt/sources.list \ # Link to build script RUN ln -sf ${SOURCE_DIR}/deployment/build.debian.armhf /build.sh -# Create the source dir -RUN mkdir -p ${SOURCE_DIR} +VOLUME ${SOURCE_DIR}/ VOLUME ${ARTIFACT_DIR}/ -COPY . ${SOURCE_DIR}/ - ENTRYPOINT ["/build.sh"] From eb632e4a0dd5d83a1aea4c710caf1ea0f3ad6b0e Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 16:01:25 -0400 Subject: [PATCH 034/517] Back up and restore control file --- deployment/build.debian.amd64 | 2 ++ deployment/build.debian.arm64 | 2 ++ deployment/build.debian.armhf | 2 ++ deployment/build.ubuntu.amd64 | 2 ++ deployment/build.ubuntu.arm64 | 2 ++ deployment/build.ubuntu.armhf | 2 ++ 6 files changed, 12 insertions(+) diff --git a/deployment/build.debian.amd64 b/deployment/build.debian.amd64 index c43585161d..0eb9ee5c83 100755 --- a/deployment/build.debian.amd64 +++ b/deployment/build.debian.amd64 @@ -10,6 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + cp debian/control debian/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -20,6 +21,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then + mv debian/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.debian.arm64 b/deployment/build.debian.arm64 index 4225c2f9df..d1ce85e2fa 100755 --- a/deployment/build.debian.arm64 +++ b/deployment/build.debian.arm64 @@ -10,6 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + cp debian/control debian/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -21,6 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then + mv debian/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.debian.armhf b/deployment/build.debian.armhf index f71a960410..3941583544 100755 --- a/deployment/build.debian.armhf +++ b/deployment/build.debian.armhf @@ -10,6 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + cp debian/control debian/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -21,6 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then + mv debian/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.amd64 b/deployment/build.ubuntu.amd64 index e74db90c43..86653cb384 100755 --- a/deployment/build.ubuntu.amd64 +++ b/deployment/build.ubuntu.amd64 @@ -10,6 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + cp debian/control debian/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -20,6 +21,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then + mv debian/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.arm64 b/deployment/build.ubuntu.arm64 index 1d91b303ad..f065170092 100755 --- a/deployment/build.ubuntu.arm64 +++ b/deployment/build.ubuntu.arm64 @@ -10,6 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + cp debian/control debian/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -21,6 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then + mv debian/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.armhf b/deployment/build.ubuntu.armhf index efdc2b65b1..679fde5ae1 100755 --- a/deployment/build.ubuntu.armhf +++ b/deployment/build.ubuntu.armhf @@ -10,6 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually + cp debian/control debian/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -21,6 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then + mv debian/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi From 6028bc0f7915a09caea881462008561424a15829 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 16:28:49 -0400 Subject: [PATCH 035/517] Port Fedora and CentOS builds and remove web build Simplifies a number of aspects of the RPM build, including moving .copr/Makefile into the "fedora/" folder (and leaving a symlink), removing the jellyfin-web build components, and renaming it jellyfin-server like Debian did. --- .copr/Makefile | 60 +---------- deployment/Dockerfile.centos.amd64 | 32 ++++++ deployment/Dockerfile.fedora.amd64 | 33 ++++++ deployment/build.centos.amd64 | 24 +++++ deployment/build.fedora.amd64 | 24 +++++ fedora/.gitignore | 3 + fedora/Makefile | 29 ++++++ fedora/README.md | 43 ++++++++ fedora/jellyfin-firewalld.xml | 9 ++ fedora/jellyfin.env | 34 +++++++ fedora/jellyfin.override.conf | 7 ++ fedora/jellyfin.service | 15 +++ fedora/jellyfin.spec | 158 +++++++++++++++++++++++++++++ fedora/jellyfin.sudoers | 19 ++++ fedora/restart.sh | 36 +++++++ 15 files changed, 467 insertions(+), 59 deletions(-) mode change 100644 => 120000 .copr/Makefile create mode 100644 deployment/Dockerfile.centos.amd64 create mode 100644 deployment/Dockerfile.fedora.amd64 create mode 100755 deployment/build.centos.amd64 create mode 100755 deployment/build.fedora.amd64 create mode 100644 fedora/.gitignore create mode 100644 fedora/Makefile create mode 100644 fedora/README.md create mode 100644 fedora/jellyfin-firewalld.xml create mode 100644 fedora/jellyfin.env create mode 100644 fedora/jellyfin.override.conf create mode 100644 fedora/jellyfin.service create mode 100644 fedora/jellyfin.spec create mode 100644 fedora/jellyfin.sudoers create mode 100755 fedora/restart.sh diff --git a/.copr/Makefile b/.copr/Makefile deleted file mode 100644 index ba330ada95..0000000000 --- a/.copr/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -VERSION := $(shell sed -ne '/^Version:/s/.* *//p' \ - deployment/fedora-package-x64/pkg-src/jellyfin.spec) - -deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz: - curl -f -L -o deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz \ - https://github.com/jellyfin/jellyfin-web/archive/v$(VERSION).tar.gz \ - || curl -f -L -o deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz \ - https://github.com/jellyfin/jellyfin-web/archive/master.tar.gz \ - -srpm: deployment/fedora-package-x64/pkg-src/jellyfin-web-$(VERSION).tar.gz - cd deployment/fedora-package-x64; \ - SOURCE_DIR=../.. \ - WORKDIR="$${PWD}"; \ - package_temporary_dir="$${WORKDIR}/pkg-dist-tmp"; \ - pkg_src_dir="$${WORKDIR}/pkg-src"; \ - GNU_TAR=1; \ - tar \ - --transform "s,^\.,jellyfin-$(VERSION)," \ - --exclude='.git*' \ - --exclude='**/.git' \ - --exclude='**/.hg' \ - --exclude='**/.vs' \ - --exclude='**/.vscode' \ - --exclude='deployment' \ - --exclude='**/bin' \ - --exclude='**/obj' \ - --exclude='**/.nuget' \ - --exclude='*.deb' \ - --exclude='*.rpm' \ - -czf "pkg-src/jellyfin-$(VERSION).tar.gz" \ - -C $${SOURCE_DIR} ./ || GNU_TAR=0; \ - if [ $${GNU_TAR} -eq 0 ]; then \ - package_temporary_dir="$$(mktemp -d)"; \ - mkdir -p "$${package_temporary_dir}/jellyfin"; \ - tar \ - --exclude='.git*' \ - --exclude='**/.git' \ - --exclude='**/.hg' \ - --exclude='**/.vs' \ - --exclude='**/.vscode' \ - --exclude='deployment' \ - --exclude='**/bin' \ - --exclude='**/obj' \ - --exclude='**/.nuget' \ - --exclude='*.deb' \ - --exclude='*.rpm' \ - -czf "$${package_temporary_dir}/jellyfin/jellyfin-$(VERSION).tar.gz" \ - -C $${SOURCE_DIR} ./; \ - mkdir -p "$${package_temporary_dir}/jellyfin-$(VERSION)"; \ - tar -xzf "$${package_temporary_dir}/jellyfin/jellyfin-$(VERSION).tar.gz" \ - -C "$${package_temporary_dir}/jellyfin-$(VERSION); \ - rm -f "$${package_temporary_dir}/jellyfin/jellyfin-$(VERSION).tar.gz"; \ - tar -czf "$${SOURCE_DIR}/SOURCES/pkg-src/jellyfin-$(VERSION).tar.gz" \ - -C "$${package_temporary_dir}" "jellyfin-$(VERSION); \ - rm -rf $${package_temporary_dir}; \ - fi; \ - rpmbuild -bs pkg-src/jellyfin.spec \ - --define "_sourcedir $$PWD/pkg-src/" \ - --define "_srcrpmdir $(outdir)" diff --git a/.copr/Makefile b/.copr/Makefile new file mode 120000 index 0000000000..ec3c90dfd9 --- /dev/null +++ b/.copr/Makefile @@ -0,0 +1 @@ +../fedora/Makefile \ No newline at end of file diff --git a/deployment/Dockerfile.centos.amd64 b/deployment/Dockerfile.centos.amd64 new file mode 100644 index 0000000000..39788cc0ee --- /dev/null +++ b/deployment/Dockerfile.centos.amd64 @@ -0,0 +1,32 @@ +FROM centos:7 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV IS_DOCKER=YES + +# Prepare CentOS environment +RUN yum update -y \ + && yum install -y epel-release \ + && yum install -y @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git + +# Install DotNET SDK +RUN rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm \ + && rpmdev-setuptree \ + && yum install -y dotnet-sdk-${SDK_VERSION} + +# Create symlinks and directories +RUN ln -sf ${SOURCE_DIR}/deployment/build.centos.amd64 /build.sh \ + && mkdir -p ${SOURCE_DIR}/SPECS \ + && ln -s ${SOURCE_DIR}/fedora/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ + && mkdir -p ${SOURCE_DIR}/SOURCES \ + && ln -s ${SOURCE_DIR}/fedora ${SOURCE_DIR}/SOURCES + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.fedora.amd64 b/deployment/Dockerfile.fedora.amd64 new file mode 100644 index 0000000000..73148763de --- /dev/null +++ b/deployment/Dockerfile.fedora.amd64 @@ -0,0 +1,33 @@ +FROM fedora:31 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV IS_DOCKER=YES + +# Prepare Fedora environment +RUN dnf update -y + +# Install build dependencies +RUN dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel + +# Install DotNET SDK +RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc \ + && curl -o /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/$(rpm -E %fedora)/prod.repo \ + && dnf install -y dotnet-sdk-${SDK_VERSION} dotnet-runtime-${SDK_VERSION} + +# Create symlinks and directories +RUN ln -sf ${SOURCE_DIR}/deployment/build.fedora.amd64 /build.sh \ + && mkdir -p ${SOURCE_DIR}/SPECS \ + && ln -s ${SOURCE_DIR}/fedora/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ + && mkdir -p ${SOURCE_DIR}/SOURCES \ + && ln -s ${SOURCE_DIR}/fedora ${SOURCE_DIR}/SOURCES + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/build.centos.amd64 b/deployment/build.centos.amd64 new file mode 100755 index 0000000000..939bbc45a4 --- /dev/null +++ b/deployment/build.centos.amd64 @@ -0,0 +1,24 @@ +#!/bin/bash + +#= CentOS/RHEL 7+ amd64 .rpm + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Build RPM +make -f fedora/Makefile srpm outdir=/root/rpmbuild/SRPMS +rpmbuild --rebuild -bb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm + +# Move the artifacts out +mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +rm -f fedora/jellyfin*.tar.gz + +popd diff --git a/deployment/build.fedora.amd64 b/deployment/build.fedora.amd64 new file mode 100755 index 0000000000..8ac99decc1 --- /dev/null +++ b/deployment/build.fedora.amd64 @@ -0,0 +1,24 @@ +#!/bin/bash + +#= Fedora 29+ amd64 .rpm + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Build RPM +make -f fedora/Makefile srpm outdir=/root/rpmbuild/SRPMS +rpmbuild -rb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm + +# Move the artifacts out +mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +rm -f fedora/jellyfin*.tar.gz + +popd diff --git a/fedora/.gitignore b/fedora/.gitignore new file mode 100644 index 0000000000..6019b98c22 --- /dev/null +++ b/fedora/.gitignore @@ -0,0 +1,3 @@ +*.rpm +*.zip +*.tar.gz \ No newline at end of file diff --git a/fedora/Makefile b/fedora/Makefile new file mode 100644 index 0000000000..1d2709a2fe --- /dev/null +++ b/fedora/Makefile @@ -0,0 +1,29 @@ +VERSION := $(shell sed -ne '/^Version:/s/.* *//p' fedora/jellyfin.spec) + +srpm: + cd fedora/; \ + SOURCE_DIR=.. \ + WORKDIR="$${PWD}"; \ + package_temporary_dir="$${WORKDIR}/pkg-dist-tmp"; \ + pkg_src_dir="$${WORKDIR}"; \ + GNU_TAR=1; \ + tar \ + --transform "s,^\.,jellyfin-server-$(VERSION)," \ + --exclude='.git*' \ + --exclude='**/.git' \ + --exclude='**/.hg' \ + --exclude='**/.vs' \ + --exclude='**/.vscode' \ + --exclude='deployment' \ + --exclude='**/bin' \ + --exclude='**/obj' \ + --exclude='**/.nuget' \ + --exclude='*.deb' \ + --exclude='*.rpm' \ + --exclude='jellyfin-server-$(VERSION).tar.gz' \ + -czf "jellyfin-server-$(VERSION).tar.gz" \ + -C $${SOURCE_DIR} ./ + cd fedora/; \ + rpmbuild -bs jellyfin.spec \ + --define "_sourcedir $$PWD/" \ + --define "_srcrpmdir $(outdir)" diff --git a/fedora/README.md b/fedora/README.md new file mode 100644 index 0000000000..7ed6f7efc6 --- /dev/null +++ b/fedora/README.md @@ -0,0 +1,43 @@ +# Jellyfin RPM + +## Build Fedora Package with docker + +Change into this directory `cd rpm-package` +Run the build script `./build-fedora-rpm.sh`. +Resulting RPM and src.rpm will be in `../../jellyfin-*.rpm` + +## ffmpeg + +The RPM package for Fedora/CentOS requires some additional repositories as ffmpeg is not in the main repositories. + +```shell +# ffmpeg from RPMfusion free +# Fedora +$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm +# CentOS 7 +$ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm +``` + +## ISO mounting + +To allow Jellyfin to mount/umount ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` +``` +# %jellyfin ALL=(ALL) NOPASSWD: /bin/mount +# %jellyfin ALL=(ALL) NOPASSWD: /bin/umount +``` + +## Building with dotnet + +Jellyfin is build with `--self-contained` so no dotnet required for runtime. + +```shell +# dotnet required for building the RPM +# Fedora +$ sudo dnf copr enable @dotnet-sig/dotnet +# CentOS +$ sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm +``` + +## TODO + +- [ ] OpenSUSE \ No newline at end of file diff --git a/fedora/jellyfin-firewalld.xml b/fedora/jellyfin-firewalld.xml new file mode 100644 index 0000000000..538c5d65f8 --- /dev/null +++ b/fedora/jellyfin-firewalld.xml @@ -0,0 +1,9 @@ + + + Jellyfin + The Free Software Media System. + + + + + diff --git a/fedora/jellyfin.env b/fedora/jellyfin.env new file mode 100644 index 0000000000..de48f13af5 --- /dev/null +++ b/fedora/jellyfin.env @@ -0,0 +1,34 @@ +# Jellyfin default configuration options + +# Use this file to override the default configurations; add additional +# options with JELLYFIN_ADD_OPTS. + +# To override the user or this config file's location, use +# /etc/systemd/system/jellyfin.service.d/override.conf + +# +# This is a POSIX shell fragment +# + +# +# General options +# + +# Program directories +JELLYFIN_DATA_DIR="/var/lib/jellyfin" +JELLYFIN_CONFIG_DIR="/etc/jellyfin" +JELLYFIN_LOG_DIR="/var/log/jellyfin" +JELLYFIN_CACHE_DIR="/var/cache/jellyfin" + +# In-App service control +JELLYFIN_RESTART_OPT="--restartpath=/usr/libexec/jellyfin/restart.sh" + +# [OPTIONAL] ffmpeg binary paths, overriding the UI-configured values +#JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/bin/ffmpeg" + +# [OPTIONAL] run Jellyfin as a headless service +#JELLYFIN_SERVICE_OPT="--service" + +# [OPTIONAL] run Jellyfin without the web app +#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" + diff --git a/fedora/jellyfin.override.conf b/fedora/jellyfin.override.conf new file mode 100644 index 0000000000..8652450bb4 --- /dev/null +++ b/fedora/jellyfin.override.conf @@ -0,0 +1,7 @@ +# Jellyfin systemd configuration options + +# Use this file to override the user or environment file location. + +[Service] +#User = jellyfin +#EnvironmentFile = /etc/sysconfig/jellyfin diff --git a/fedora/jellyfin.service b/fedora/jellyfin.service new file mode 100644 index 0000000000..f3dc594b1c --- /dev/null +++ b/fedora/jellyfin.service @@ -0,0 +1,15 @@ +[Unit] +After=network.target +Description=Jellyfin is a free software media system that puts you in control of managing and streaming your media. + +[Service] +EnvironmentFile=/etc/sysconfig/jellyfin +WorkingDirectory=/var/lib/jellyfin +ExecStart=/usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} +TimeoutSec=15 +Restart=on-failure +User=jellyfin +Group=jellyfin + +[Install] +WantedBy=multi-user.target diff --git a/fedora/jellyfin.spec b/fedora/jellyfin.spec new file mode 100644 index 0000000000..e6a3170b56 --- /dev/null +++ b/fedora/jellyfin.spec @@ -0,0 +1,158 @@ +%global debug_package %{nil} +# Set the dotnet runtime +%if 0%{?fedora} +%global dotnet_runtime fedora-x64 +%else +%global dotnet_runtime centos-x64 +%endif + +Name: jellyfin-server +Version: 10.6.0 +Release: 1%{?dist} +Summary: The Free Software Media Browser +License: GPLv2 +URL: https://jellyfin.media +# Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` +Source0: jellyfin-server-%{version}.tar.gz +Source11: jellyfin.service +Source12: jellyfin.env +Source13: jellyfin.sudoers +Source14: restart.sh +Source15: jellyfin.override.conf +Source16: jellyfin-firewalld.xml + +%{?systemd_requires} +BuildRequires: systemd +Requires(pre): shadow-utils +BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel +Requires: libcurl, fontconfig, freetype, openssl, glibc libicu +# Requirements not packaged in main repos +# COPR @dotnet-sig/dotnet or +# https://packages.microsoft.com/rhel/7/prod/ +BuildRequires: dotnet-runtime-3.1, dotnet-sdk-3.1 +# RPMfusion free +Requires: ffmpeg + +# Disable Automatic Dependency Processing +AutoReqProv: no + +%description +Jellyfin is a free software media system that puts you in control of managing and streaming your media. + + +%prep +%autosetup -n jellyfin-server-%{version} -b 0 + +%build + +%install +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime %{dotnet_runtime} \ + "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server +%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/jellyfin/LICENSE +%{__install} -D -m 0644 %{SOURCE15} %{buildroot}%{_sysconfdir}/systemd/system/jellyfin.service.d/override.conf +%{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/jellyfin/logging.json +%{__mkdir} -p %{buildroot}%{_bindir} +tee %{buildroot}%{_bindir}/jellyfin << EOF +#!/bin/sh +exec %{_libdir}/jellyfin/jellyfin \${@} +EOF +%{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin +%{__mkdir} -p %{buildroot}%{_sysconfdir}/jellyfin +%{__mkdir} -p %{buildroot}%{_var}/log/jellyfin +%{__mkdir} -p %{buildroot}%{_var}/cache/jellyfin + +%{__install} -D -m 0644 %{SOURCE11} %{buildroot}%{_unitdir}/jellyfin.service +%{__install} -D -m 0644 %{SOURCE12} %{buildroot}%{_sysconfdir}/sysconfig/jellyfin +%{__install} -D -m 0600 %{SOURCE13} %{buildroot}%{_sysconfdir}/sudoers.d/jellyfin-sudoers +%{__install} -D -m 0755 %{SOURCE14} %{buildroot}%{_libexecdir}/jellyfin/restart.sh +%{__install} -D -m 0644 %{SOURCE16} %{buildroot}%{_prefix}/lib/firewalld/services/jellyfin.xml + +%files +%attr(755,root,root) %{_bindir}/jellyfin +%{_libdir}/jellyfin/*.json +%{_libdir}/jellyfin/*.dll +%{_libdir}/jellyfin/*.so +%{_libdir}/jellyfin/*.a +%{_libdir}/jellyfin/createdump +# Needs 755 else only root can run it since binary build by dotnet is 722 +%attr(755,root,root) %{_libdir}/jellyfin/jellyfin +%{_libdir}/jellyfin/SOS_README.md +%{_unitdir}/jellyfin.service +%{_libexecdir}/jellyfin/restart.sh +%{_prefix}/lib/firewalld/services/jellyfin.xml +%attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/jellyfin +%config %{_sysconfdir}/sysconfig/jellyfin +%config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/jellyfin-sudoers +%config(noreplace) %{_sysconfdir}/systemd/system/jellyfin.service.d/override.conf +%config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/jellyfin/logging.json +%attr(750,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin +%attr(-,jellyfin,jellyfin) %dir %{_var}/log/jellyfin +%attr(750,jellyfin,jellyfin) %dir %{_var}/cache/jellyfin +%{_datadir}/licenses/jellyfin/LICENSE + +%pre +getent group jellyfin >/dev/null || groupadd -r jellyfin +getent passwd jellyfin >/dev/null || \ + useradd -r -g jellyfin -d %{_sharedstatedir}/jellyfin -s /sbin/nologin \ + -c "Jellyfin default user" jellyfin +exit 0 + +%post +# Move existing configuration cache and logs to their new locations and symlink them. +if [ $1 -gt 1 ] ; then + service_state=$(systemctl is-active jellyfin.service) + if [ "${service_state}" = "active" ]; then + systemctl stop jellyfin.service + fi + if [ ! -L %{_sharedstatedir}/jellyfin/config ]; then + mv %{_sharedstatedir}/jellyfin/config/* %{_sysconfdir}/jellyfin/ + rmdir %{_sharedstatedir}/jellyfin/config + ln -sf %{_sysconfdir}/jellyfin %{_sharedstatedir}/jellyfin/config + fi + if [ ! -L %{_sharedstatedir}/jellyfin/logs ]; then + mv %{_sharedstatedir}/jellyfin/logs/* %{_var}/log/jellyfin + rmdir %{_sharedstatedir}/jellyfin/logs + ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/jellyfin/logs + fi + if [ ! -L %{_sharedstatedir}/jellyfin/cache ]; then + mv %{_sharedstatedir}/jellyfin/cache/* %{_var}/cache/jellyfin + rmdir %{_sharedstatedir}/jellyfin/cache + ln -sf %{_var}/cache/jellyfin %{_sharedstatedir}/jellyfin/cache + fi + if [ "${service_state}" = "active" ]; then + systemctl start jellyfin.service + fi +fi +%systemd_post jellyfin.service + +%preun +%systemd_preun jellyfin.service + +%postun +%systemd_postun_with_restart jellyfin.service + +%changelog +* Mon Mar 23 2020 Jellyfin Packaging Team +- Forthcoming stable release +* Fri Oct 11 2019 Jellyfin Packaging Team +- New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 +* Sat Aug 31 2019 Jellyfin Packaging Team +- New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 +* Wed Jul 24 2019 Jellyfin Packaging Team +- New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 +* Sat Jul 06 2019 Jellyfin Packaging Team +- New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 +* Sun Jun 09 2019 Jellyfin Packaging Team +- New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 +* Thu Jun 06 2019 Jellyfin Packaging Team +- New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 +* Fri May 17 2019 Jellyfin Packaging Team +- New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 +* Tue Apr 30 2019 Jellyfin Packaging Team +- New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 +* Sat Apr 20 2019 Jellyfin Packaging Team +- New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 +* Fri Apr 19 2019 Jellyfin Packaging Team +- New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 diff --git a/fedora/jellyfin.sudoers b/fedora/jellyfin.sudoers new file mode 100644 index 0000000000..dd245af4b8 --- /dev/null +++ b/fedora/jellyfin.sudoers @@ -0,0 +1,19 @@ +# Allow jellyfin group to start, stop and restart itself +Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin +Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin +Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin + + +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD + +Defaults!RESTARTSERVER_SYSTEMD !requiretty +Defaults!STARTSERVER_SYSTEMD !requiretty +Defaults!STOPSERVER_SYSTEMD !requiretty + +# Allow the server to mount iso images +jellyfin ALL=(ALL) NOPASSWD: /bin/mount +jellyfin ALL=(ALL) NOPASSWD: /bin/umount + +Defaults:jellyfin !requiretty diff --git a/fedora/restart.sh b/fedora/restart.sh new file mode 100755 index 0000000000..9e53efecd0 --- /dev/null +++ b/fedora/restart.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# restart.sh - Jellyfin server restart script +# Part of the Jellyfin project (https://github.com/jellyfin) +# +# This script restarts the Jellyfin daemon on Linux when using +# the Restart button on the admin dashboard. It supports the +# systemctl, service, and traditional /etc/init.d (sysv) restart +# methods, chosen automatically by which one is found first (in +# that order). +# +# This script is used by the Debian/Ubuntu/Fedora/CentOS packages. + +get_service_command() { + for command in systemctl service; do + if which $command &>/dev/null; then + echo $command && return + fi + done + echo "sysv" +} + +cmd="$( get_service_command )" +echo "Detected service control platform '$cmd'; using it to restart Jellyfin..." +case $cmd in + 'systemctl') + echo "sleep 2; /usr/bin/sudo $( which systemctl ) restart jellyfin" | at now + ;; + 'service') + echo "sleep 2; /usr/bin/sudo $( which service ) jellyfin restart" | at now + ;; + 'sysv') + echo "sleep 2; /usr/bin/sudo /etc/init.d/jellyfin restart" | at now + ;; +esac +exit 0 From cf6dc609b72fd9b388c987ae38c0a8bf95168d15 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 17:54:17 -0400 Subject: [PATCH 036/517] Fix up single-segment platform names --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 5d3f8ec713..8256f9ea31 100755 --- a/build.sh +++ b/build.sh @@ -24,7 +24,7 @@ usage() { list_platforms() { declare -a platforms platforms=( - $( find deployment -maxdepth 1 -mindepth 1 -name "build.*" | awk -F'.' '{ $1=""; print $2 "." $3 }' | sort ) + $( find deployment -maxdepth 1 -mindepth 1 -name "build.*" | awk -F'.' '{ $1=""; printf $2; if ($3 != ""){ printf "." $3; } print ""; }' | sort ) ) echo -e "Valid platforms:" echo From 8e0a33c1aadabd91765594e8d9d5c3a53933b26d Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 18:01:28 -0400 Subject: [PATCH 037/517] Handle single- or triple-part platform names --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 8256f9ea31..86c8447933 100755 --- a/build.sh +++ b/build.sh @@ -24,7 +24,7 @@ usage() { list_platforms() { declare -a platforms platforms=( - $( find deployment -maxdepth 1 -mindepth 1 -name "build.*" | awk -F'.' '{ $1=""; printf $2; if ($3 != ""){ printf "." $3; } print ""; }' | sort ) + $( find deployment -maxdepth 1 -mindepth 1 -name "build.*" | awk -F'.' '{ $1=""; printf $2; if ($3 != ""){ printf "." $3; }; if ($4 != ""){ printf "." $4; }; print ""; }' | sort ) ) echo -e "Valid platforms:" echo From ab8de37080a985c742694722f311d719ec64bdc8 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 18:01:42 -0400 Subject: [PATCH 038/517] Add .tar.gz-based builds --- deployment/Dockerfile.linux.amd64 | 31 +++++++++++++++++++++++++++++++ deployment/Dockerfile.macos.amd64 | 31 +++++++++++++++++++++++++++++++ deployment/Dockerfile.portable | 30 ++++++++++++++++++++++++++++++ deployment/build.linux.amd64 | 27 +++++++++++++++++++++++++++ deployment/build.macos.amd64 | 27 +++++++++++++++++++++++++++ deployment/build.portable | 27 +++++++++++++++++++++++++++ 6 files changed, 173 insertions(+) create mode 100644 deployment/Dockerfile.linux.amd64 create mode 100644 deployment/Dockerfile.macos.amd64 create mode 100644 deployment/Dockerfile.portable create mode 100755 deployment/build.linux.amd64 create mode 100755 deployment/build.macos.amd64 create mode 100755 deployment/build.portable diff --git a/deployment/Dockerfile.linux.amd64 b/deployment/Dockerfile.linux.amd64 new file mode 100644 index 0000000000..d8bec92145 --- /dev/null +++ b/deployment/Dockerfile.linux.amd64 @@ -0,0 +1,31 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to docker-build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.linux.amd64 /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.macos.amd64 b/deployment/Dockerfile.macos.amd64 new file mode 100644 index 0000000000..aaf9a9692f --- /dev/null +++ b/deployment/Dockerfile.macos.amd64 @@ -0,0 +1,31 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to docker-build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.macos.amd64 /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/Dockerfile.portable b/deployment/Dockerfile.portable new file mode 100644 index 0000000000..2893e140df --- /dev/null +++ b/deployment/Dockerfile.portable @@ -0,0 +1,30 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to docker-build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.portable /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/build.linux.amd64 b/deployment/build.linux.amd64 new file mode 100755 index 0000000000..0cbbd05cf9 --- /dev/null +++ b/deployment/build.linux.amd64 @@ -0,0 +1,27 @@ +#!/bin/bash + +#= Generic Linux amd64 .tar.gz + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build archives +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output dist/jellyfin-server_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" +tar -czf jellyfin-server_${version}_linux-amd64.tar.gz -C dist jellyfin-server_${version} +rm -rf dist/jellyfin-server_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/deployment/build.macos.amd64 b/deployment/build.macos.amd64 new file mode 100755 index 0000000000..4dca2b6438 --- /dev/null +++ b/deployment/build.macos.amd64 @@ -0,0 +1,27 @@ +#!/bin/bash + +#= MacOS 10.13+ amd64 .tar.gz + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build archives +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output dist/jellyfin-server_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" +tar -czf jellyfin-server_${version}_macos-amd64.tar.gz -C dist jellyfin-server_${version} +rm -rf dist/jellyfin-server_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/deployment/build.portable b/deployment/build.portable new file mode 100755 index 0000000000..1e8a4ab623 --- /dev/null +++ b/deployment/build.portable @@ -0,0 +1,27 @@ +#!/bin/bash + +#= Portable .NET DLL .tar.gz + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build archives +dotnet publish Jellyfin.Server --configuration Release --output dist/jellyfin-server_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" +tar -czf jellyfin-server_${version}_portable.tar.gz -C dist jellyfin-server_${version} +rm -rf dist/jellyfin-server_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd From 0242ce5fee689442472505be94000233c464ffbd Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 18:10:34 -0400 Subject: [PATCH 039/517] Add Windows build --- build.yaml | 25 +++++---- deployment/Dockerfile.windows.amd64 | 30 +++++++++++ deployment/build.windows.amd64 | 54 +++++++++++++++++++ .../windows => windows}/build-jellyfin.ps1 | 0 .../old/windows => windows}/dependencies.txt | 0 .../dialogs/confirmation.nsddef | 0 .../dialogs/confirmation.nsdinc | 0 .../dialogs/service-config.nsddef | 0 .../dialogs/service-config.nsdinc | 0 .../dialogs/setuptype.nsddef | 0 .../dialogs/setuptype.nsdinc | 0 .../windows => windows}/helpers/ShowError.nsh | 0 .../windows => windows}/helpers/StrSlash.nsh | 0 .../old/windows => windows}/jellyfin.nsi | 0 .../legacy/install-jellyfin.ps1 | 0 .../windows => windows}/legacy/install.bat | 0 16 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 deployment/Dockerfile.windows.amd64 create mode 100755 deployment/build.windows.amd64 rename {deployment/old/windows => windows}/build-jellyfin.ps1 (100%) rename {deployment/old/windows => windows}/dependencies.txt (100%) rename {deployment/old/windows => windows}/dialogs/confirmation.nsddef (100%) rename {deployment/old/windows => windows}/dialogs/confirmation.nsdinc (100%) rename {deployment/old/windows => windows}/dialogs/service-config.nsddef (100%) rename {deployment/old/windows => windows}/dialogs/service-config.nsdinc (100%) rename {deployment/old/windows => windows}/dialogs/setuptype.nsddef (100%) rename {deployment/old/windows => windows}/dialogs/setuptype.nsdinc (100%) rename {deployment/old/windows => windows}/helpers/ShowError.nsh (100%) rename {deployment/old/windows => windows}/helpers/StrSlash.nsh (100%) rename {deployment/old/windows => windows}/jellyfin.nsi (100%) rename {deployment/old/windows => windows}/legacy/install-jellyfin.ps1 (100%) rename {deployment/old/windows => windows}/legacy/install.bat (100%) diff --git a/build.yaml b/build.yaml index 123f77fb89..a76539d1f3 100644 --- a/build.yaml +++ b/build.yaml @@ -1,18 +1,17 @@ --- # We just wrap `build` so this is really it name: "jellyfin" -version: "10.5.0" +version: "10.6.0" packages: - - debian-package-x64 - - debian-package-armhf - - debian-package-arm64 - - ubuntu-package-x64 - - ubuntu-package-armhf - - ubuntu-package-arm64 - - fedora-package-x64 - - centos-package-x64 - - linux-x64 - - macos + - debian.amd64 + - debian.arm64 + - debian.armhf + - ubuntu.amd64 + - ubuntu.arm64 + - ubuntu.armhf + - fedora.amd64 + - centos.amd64 + - linux.amd64 + - macos.amd64 + - windows.amd64 - portable - - win-x64 - - win-x86 diff --git a/deployment/Dockerfile.windows.amd64 b/deployment/Dockerfile.windows.amd64 new file mode 100644 index 0000000000..0397a023e2 --- /dev/null +++ b/deployment/Dockerfile.windows.amd64 @@ -0,0 +1,30 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV IS_DOCKER=YES + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to docker-build script +RUN ln -sf ${SOURCE_DIR}/deployment/build.windows.amd64 /build.sh + +VOLUME ${SOURCE_DIR}/ + +VOLUME ${ARTIFACT_DIR}/ + +ENTRYPOINT ["/build.sh"] diff --git a/deployment/build.windows.amd64 b/deployment/build.windows.amd64 new file mode 100755 index 0000000000..39bd41f990 --- /dev/null +++ b/deployment/build.windows.amd64 @@ -0,0 +1,54 @@ +#!/bin/bash + +#= Windows 7+ amd64 (x64) .zip + +set -o errexit +set -o xtrace + +# Version variables +NSSM_VERSION="nssm-2.24-101-g897c7ad" +NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" +FFMPEG_VERSION="ffmpeg-4.2.1-win64-static" +FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win64/static/${FFMPEG_VERSION}.zip" + +# Move to source directory +pushd ${SOURCE_DIR} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +output_dir="dist/jellyfin-server_${version}" + +# Build binary +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output ${output_dir}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" + +# Prepare addins +addin_build_dir="$( mktemp -d )" +wget ${NSSM_URL} -O ${addin_build_dir}/nssm.zip +wget ${FFMPEG_URL} -O ${addin_build_dir}/ffmpeg.zip +unzip ${addin_build_dir}/nssm.zip -d ${addin_build_dir} +cp ${addin_build_dir}/${NSSM_VERSION}/win64/nssm.exe ${output_dir}/nssm.exe +unzip ${addin_build_dir}/ffmpeg.zip -d ${addin_build_dir} +cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffmpeg.exe ${output_dir}/ffmpeg.exe +cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffprobe.exe ${output_dir}/ffprobe.exe +rm -rf ${addin_build_dir} + +# Prepare scripts +cp ${SOURCE_DIR}/windows/legacy/install-jellyfin.ps1 ${output_dir}/install-jellyfin.ps1 +cp ${SOURCE_DIR}/windows/legacy/install.bat ${output_dir}/install.bat + +# Create zip package +pushd dist +zip -qr jellyfin-server_${version}.portable.zip jellyfin-server_${version} +popd +rm -rf ${output_dir} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv dist/jellyfin[-_]*.zip ${ARTIFACT_DIR}/ + +if [[ ${IS_DOCKER} == YES ]]; then + chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} +fi + +popd diff --git a/deployment/old/windows/build-jellyfin.ps1 b/windows/build-jellyfin.ps1 similarity index 100% rename from deployment/old/windows/build-jellyfin.ps1 rename to windows/build-jellyfin.ps1 diff --git a/deployment/old/windows/dependencies.txt b/windows/dependencies.txt similarity index 100% rename from deployment/old/windows/dependencies.txt rename to windows/dependencies.txt diff --git a/deployment/old/windows/dialogs/confirmation.nsddef b/windows/dialogs/confirmation.nsddef similarity index 100% rename from deployment/old/windows/dialogs/confirmation.nsddef rename to windows/dialogs/confirmation.nsddef diff --git a/deployment/old/windows/dialogs/confirmation.nsdinc b/windows/dialogs/confirmation.nsdinc similarity index 100% rename from deployment/old/windows/dialogs/confirmation.nsdinc rename to windows/dialogs/confirmation.nsdinc diff --git a/deployment/old/windows/dialogs/service-config.nsddef b/windows/dialogs/service-config.nsddef similarity index 100% rename from deployment/old/windows/dialogs/service-config.nsddef rename to windows/dialogs/service-config.nsddef diff --git a/deployment/old/windows/dialogs/service-config.nsdinc b/windows/dialogs/service-config.nsdinc similarity index 100% rename from deployment/old/windows/dialogs/service-config.nsdinc rename to windows/dialogs/service-config.nsdinc diff --git a/deployment/old/windows/dialogs/setuptype.nsddef b/windows/dialogs/setuptype.nsddef similarity index 100% rename from deployment/old/windows/dialogs/setuptype.nsddef rename to windows/dialogs/setuptype.nsddef diff --git a/deployment/old/windows/dialogs/setuptype.nsdinc b/windows/dialogs/setuptype.nsdinc similarity index 100% rename from deployment/old/windows/dialogs/setuptype.nsdinc rename to windows/dialogs/setuptype.nsdinc diff --git a/deployment/old/windows/helpers/ShowError.nsh b/windows/helpers/ShowError.nsh similarity index 100% rename from deployment/old/windows/helpers/ShowError.nsh rename to windows/helpers/ShowError.nsh diff --git a/deployment/old/windows/helpers/StrSlash.nsh b/windows/helpers/StrSlash.nsh similarity index 100% rename from deployment/old/windows/helpers/StrSlash.nsh rename to windows/helpers/StrSlash.nsh diff --git a/deployment/old/windows/jellyfin.nsi b/windows/jellyfin.nsi similarity index 100% rename from deployment/old/windows/jellyfin.nsi rename to windows/jellyfin.nsi diff --git a/deployment/old/windows/legacy/install-jellyfin.ps1 b/windows/legacy/install-jellyfin.ps1 similarity index 100% rename from deployment/old/windows/legacy/install-jellyfin.ps1 rename to windows/legacy/install-jellyfin.ps1 diff --git a/deployment/old/windows/legacy/install.bat b/windows/legacy/install.bat similarity index 100% rename from deployment/old/windows/legacy/install.bat rename to windows/legacy/install.bat From 9169861baab62919e661ec663998c5a4436e4547 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 18:18:38 -0400 Subject: [PATCH 040/517] Add CODEOWNERS for GitHub --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..e902dc7124 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +# Joshua must review all changes to deployment and build.sh +deployment/* @joshuaboniface +build.sh @joshuaboniface From de66ab4d832664abb5c17005d326e543446aae7d Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 18:39:11 -0400 Subject: [PATCH 041/517] Use git checkout instead of file copies to clean --- deployment/Dockerfile.debian.amd64 | 2 +- deployment/Dockerfile.debian.arm64 | 2 +- deployment/Dockerfile.debian.armhf | 2 +- deployment/Dockerfile.ubuntu.amd64 | 2 +- deployment/Dockerfile.ubuntu.arm64 | 2 +- deployment/Dockerfile.ubuntu.armhf | 2 +- deployment/build.debian.amd64 | 2 +- deployment/build.debian.arm64 | 2 +- deployment/build.debian.armhf | 2 +- deployment/build.ubuntu.amd64 | 2 +- deployment/build.ubuntu.arm64 | 2 +- deployment/build.ubuntu.armhf | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/deployment/Dockerfile.debian.amd64 b/deployment/Dockerfile.debian.amd64 index b5a0380489..ea2aba5a89 100644 --- a/deployment/Dockerfile.debian.amd64 +++ b/deployment/Dockerfile.debian.amd64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 git # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.debian.arm64 b/deployment/Dockerfile.debian.arm64 index cfe562df33..db8485b43d 100644 --- a/deployment/Dockerfile.debian.arm64 +++ b/deployment/Dockerfile.debian.arm64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf index ea8c8c8e62..717bc3c894 100644 --- a/deployment/Dockerfile.debian.armhf +++ b/deployment/Dockerfile.debian.armhf @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64 index e61be4efcc..7c2b26dedd 100644 --- a/deployment/Dockerfile.ubuntu.amd64 +++ b/deployment/Dockerfile.ubuntu.amd64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 git # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 index e34ef7edd1..27f8ec11b5 100644 --- a/deployment/Dockerfile.ubuntu.arm64 +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf index 6f92c81ab1..c888c42df6 100644 --- a/deployment/Dockerfile.ubuntu.armhf +++ b/deployment/Dockerfile.ubuntu.armhf @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/build.debian.amd64 b/deployment/build.debian.amd64 index 0eb9ee5c83..8e205867b8 100755 --- a/deployment/build.debian.amd64 +++ b/deployment/build.debian.amd64 @@ -21,7 +21,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - mv debian/control.orig debian/control + git checkout debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.debian.arm64 b/deployment/build.debian.arm64 index d1ce85e2fa..436602d195 100755 --- a/deployment/build.debian.arm64 +++ b/deployment/build.debian.arm64 @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - mv debian/control.orig debian/control + git checkout debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.debian.armhf b/deployment/build.debian.armhf index 3941583544..9ca57b1e46 100755 --- a/deployment/build.debian.armhf +++ b/deployment/build.debian.armhf @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - mv debian/control.orig debian/control + git checkout debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.amd64 b/deployment/build.ubuntu.amd64 index 86653cb384..2b789cc475 100755 --- a/deployment/build.ubuntu.amd64 +++ b/deployment/build.ubuntu.amd64 @@ -21,7 +21,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - mv debian/control.orig debian/control + git checkout debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.arm64 b/deployment/build.ubuntu.arm64 index f065170092..9b4e548501 100755 --- a/deployment/build.ubuntu.arm64 +++ b/deployment/build.ubuntu.arm64 @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - mv debian/control.orig debian/control + git checkout debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.armhf b/deployment/build.ubuntu.armhf index 679fde5ae1..59912a14f5 100755 --- a/deployment/build.ubuntu.armhf +++ b/deployment/build.ubuntu.armhf @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - mv debian/control.orig debian/control + git checkout debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi From b95bd0e67874f925918eb912d445fb202e4fcee0 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 18:42:09 -0400 Subject: [PATCH 042/517] Bump shared_version to 10.6.0 too --- SharedVersion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SharedVersion.cs b/SharedVersion.cs index d741f379d2..6981c1ca9d 100644 --- a/SharedVersion.cs +++ b/SharedVersion.cs @@ -1,4 +1,4 @@ using System.Reflection; -[assembly: AssemblyVersion("10.5.0")] -[assembly: AssemblyFileVersion("10.5.0")] +[assembly: AssemblyVersion("10.6.0")] +[assembly: AssemblyFileVersion("10.6.0")] From a561d4ca417b45e983bfe46a70397fb44f7b78a3 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 18:43:54 -0400 Subject: [PATCH 043/517] Remove arch from macos --- build.yaml | 2 +- deployment/{Dockerfile.macos.amd64 => Dockerfile.macos} | 2 +- deployment/{build.macos.amd64 => build.macos} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename deployment/{Dockerfile.macos.amd64 => Dockerfile.macos} (94%) rename deployment/{build.macos.amd64 => build.macos} (96%) diff --git a/build.yaml b/build.yaml index a76539d1f3..9e590e5a01 100644 --- a/build.yaml +++ b/build.yaml @@ -12,6 +12,6 @@ packages: - fedora.amd64 - centos.amd64 - linux.amd64 - - macos.amd64 - windows.amd64 + - macos - portable diff --git a/deployment/Dockerfile.macos.amd64 b/deployment/Dockerfile.macos similarity index 94% rename from deployment/Dockerfile.macos.amd64 rename to deployment/Dockerfile.macos index aaf9a9692f..ba5da40190 100644 --- a/deployment/Dockerfile.macos.amd64 +++ b/deployment/Dockerfile.macos @@ -22,7 +22,7 @@ RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4 && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet # Link to docker-build script -RUN ln -sf ${SOURCE_DIR}/deployment/build.macos.amd64 /build.sh +RUN ln -sf ${SOURCE_DIR}/deployment/build.macos /build.sh VOLUME ${SOURCE_DIR}/ diff --git a/deployment/build.macos.amd64 b/deployment/build.macos similarity index 96% rename from deployment/build.macos.amd64 rename to deployment/build.macos index 4dca2b6438..16be29eeef 100755 --- a/deployment/build.macos.amd64 +++ b/deployment/build.macos @@ -1,6 +1,6 @@ #!/bin/bash -#= MacOS 10.13+ amd64 .tar.gz +#= MacOS 10.13+ .tar.gz set -o errexit set -o xtrace From c478a43fd56993062622c3252be938b01e80854c Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 21:44:33 -0400 Subject: [PATCH 044/517] Update package description for Debian --- debian/control | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index f473dc41d2..648e28ae81 100644 --- a/debian/control +++ b/debian/control @@ -26,5 +26,5 @@ Depends: at, libfreetype6, libssl1.1 Recommends: jellyfin-web -Description: Jellyfin is a home media server. - It is built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono. It features a REST-based api with built-in documentation to facilitate client development. We also have client libraries for our api to enable rapid development. +Description: Jellyfin is the Free Software Media System. + This package provides the Jellyfin server backend and API. From e87a10235b960bf28a6a76da762b62a0f0399e2c Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 21:49:07 -0400 Subject: [PATCH 045/517] Go back to cp-based control archive but right --- deployment/Dockerfile.debian.amd64 | 2 +- deployment/Dockerfile.debian.arm64 | 2 +- deployment/Dockerfile.debian.armhf | 2 +- deployment/Dockerfile.ubuntu.amd64 | 2 +- deployment/Dockerfile.ubuntu.arm64 | 2 +- deployment/Dockerfile.ubuntu.armhf | 2 +- deployment/build.debian.amd64 | 4 ++-- deployment/build.debian.arm64 | 4 ++-- deployment/build.debian.armhf | 4 ++-- deployment/build.ubuntu.amd64 | 4 ++-- deployment/build.ubuntu.arm64 | 4 ++-- deployment/build.ubuntu.armhf | 4 ++-- 12 files changed, 18 insertions(+), 18 deletions(-) diff --git a/deployment/Dockerfile.debian.amd64 b/deployment/Dockerfile.debian.amd64 index ea2aba5a89..b5a0380489 100644 --- a/deployment/Dockerfile.debian.amd64 +++ b/deployment/Dockerfile.debian.amd64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 git + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.debian.arm64 b/deployment/Dockerfile.debian.arm64 index db8485b43d..cfe562df33 100644 --- a/deployment/Dockerfile.debian.arm64 +++ b/deployment/Dockerfile.debian.arm64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.debian.armhf b/deployment/Dockerfile.debian.armhf index 717bc3c894..ea8c8c8e62 100644 --- a/deployment/Dockerfile.debian.armhf +++ b/deployment/Dockerfile.debian.armhf @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.ubuntu.amd64 b/deployment/Dockerfile.ubuntu.amd64 index 7c2b26dedd..e61be4efcc 100644 --- a/deployment/Dockerfile.ubuntu.amd64 +++ b/deployment/Dockerfile.ubuntu.amd64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 git + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 index 27f8ec11b5..e34ef7edd1 100644 --- a/deployment/Dockerfile.ubuntu.arm64 +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf index c888c42df6..6f92c81ab1 100644 --- a/deployment/Dockerfile.ubuntu.armhf +++ b/deployment/Dockerfile.ubuntu.armhf @@ -12,7 +12,7 @@ ENV IS_DOCKER=YES # Prepare Debian build environment RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv git + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv # Install dotnet repository # https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current diff --git a/deployment/build.debian.amd64 b/deployment/build.debian.amd64 index 8e205867b8..beaf02bee2 100755 --- a/deployment/build.debian.amd64 +++ b/deployment/build.debian.amd64 @@ -10,7 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually - cp debian/control debian/control.orig + cp -a debian/control /tmp/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -21,7 +21,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - git checkout debian/control + cp -a /tmp/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.debian.arm64 b/deployment/build.debian.arm64 index 436602d195..6394dddb02 100755 --- a/deployment/build.debian.arm64 +++ b/deployment/build.debian.arm64 @@ -10,7 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually - cp debian/control debian/control.orig + cp -a debian/control /tmp/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - git checkout debian/control + cp -a /tmp/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.debian.armhf b/deployment/build.debian.armhf index 9ca57b1e46..d12660760f 100755 --- a/deployment/build.debian.armhf +++ b/deployment/build.debian.armhf @@ -10,7 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually - cp debian/control debian/control.orig + cp -a debian/control /tmp/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - git checkout debian/control + cp -a /tmp/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.amd64 b/deployment/build.ubuntu.amd64 index 2b789cc475..1b90f68f46 100755 --- a/deployment/build.ubuntu.amd64 +++ b/deployment/build.ubuntu.amd64 @@ -10,7 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually - cp debian/control debian/control.orig + cp -a debian/control /tmp/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -21,7 +21,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - git checkout debian/control + cp -a /tmp/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.arm64 b/deployment/build.ubuntu.arm64 index 9b4e548501..c0a31d764f 100755 --- a/deployment/build.ubuntu.arm64 +++ b/deployment/build.ubuntu.arm64 @@ -10,7 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually - cp debian/control debian/control.orig + cp -a debian/control /tmp/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - git checkout debian/control + cp -a /tmp/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi diff --git a/deployment/build.ubuntu.armhf b/deployment/build.ubuntu.armhf index 59912a14f5..e2129357dd 100755 --- a/deployment/build.ubuntu.armhf +++ b/deployment/build.ubuntu.armhf @@ -10,7 +10,7 @@ pushd ${SOURCE_DIR} if [[ ${IS_DOCKER} == YES ]]; then # Remove build-dep for dotnet-sdk-3.1, since it's installed manually - cp debian/control debian/control.orig + cp -a debian/control /tmp/control.orig sed -i '/dotnet-sdk-3.1,/d' debian/control fi @@ -22,7 +22,7 @@ mkdir -p ${ARTIFACT_DIR}/ mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then - git checkout debian/control + cp -a /tmp/control.orig debian/control chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} fi From be9eb0f19ed207cabaad48c5b713ac80d9d77397 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 22:51:12 -0400 Subject: [PATCH 046/517] Unify dep installation and update --- deployment/Dockerfile.fedora.amd64 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/deployment/Dockerfile.fedora.amd64 b/deployment/Dockerfile.fedora.amd64 index 73148763de..01b99deb6d 100644 --- a/deployment/Dockerfile.fedora.amd64 +++ b/deployment/Dockerfile.fedora.amd64 @@ -9,10 +9,8 @@ ENV ARTIFACT_DIR=/dist ENV IS_DOCKER=YES # Prepare Fedora environment -RUN dnf update -y - -# Install build dependencies -RUN dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel +RUN dnf update -y \ + && dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel # Install DotNET SDK RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc \ From fc5e9324920f5c4bf1341ff99b4e8fd2c07069ef Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 22:55:37 -0400 Subject: [PATCH 047/517] Fix makefile formatting --- fedora/Makefile | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/fedora/Makefile b/fedora/Makefile index 1d2709a2fe..5a76d7d944 100644 --- a/fedora/Makefile +++ b/fedora/Makefile @@ -2,27 +2,27 @@ VERSION := $(shell sed -ne '/^Version:/s/.* *//p' fedora/jellyfin.spec) srpm: cd fedora/; \ - SOURCE_DIR=.. \ - WORKDIR="$${PWD}"; \ - package_temporary_dir="$${WORKDIR}/pkg-dist-tmp"; \ - pkg_src_dir="$${WORKDIR}"; \ - GNU_TAR=1; \ - tar \ - --transform "s,^\.,jellyfin-server-$(VERSION)," \ - --exclude='.git*' \ - --exclude='**/.git' \ - --exclude='**/.hg' \ - --exclude='**/.vs' \ - --exclude='**/.vscode' \ - --exclude='deployment' \ - --exclude='**/bin' \ - --exclude='**/obj' \ - --exclude='**/.nuget' \ - --exclude='*.deb' \ - --exclude='*.rpm' \ - --exclude='jellyfin-server-$(VERSION).tar.gz' \ - -czf "jellyfin-server-$(VERSION).tar.gz" \ - -C $${SOURCE_DIR} ./ + SOURCE_DIR=.. \ + WORKDIR="$${PWD}"; \ + package_temporary_dir="$${WORKDIR}/pkg-dist-tmp"; \ + pkg_src_dir="$${WORKDIR}"; \ + GNU_TAR=1; \ + tar \ + --transform "s,^\.,jellyfin-server-$(VERSION)," \ + --exclude='.git*' \ + --exclude='**/.git' \ + --exclude='**/.hg' \ + --exclude='**/.vs' \ + --exclude='**/.vscode' \ + --exclude='deployment' \ + --exclude='**/bin' \ + --exclude='**/obj' \ + --exclude='**/.nuget' \ + --exclude='*.deb' \ + --exclude='*.rpm' \ + --exclude='jellyfin-server-$(VERSION).tar.gz' \ + -czf "jellyfin-server-$(VERSION).tar.gz" \ + -C $${SOURCE_DIR} ./ cd fedora/; \ rpmbuild -bs jellyfin.spec \ --define "_sourcedir $$PWD/" \ From 891aa7c25585dacc490590bc7337b00161a781e6 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 23 Mar 2020 23:00:35 -0400 Subject: [PATCH 048/517] Update info in Fedora spec --- fedora/jellyfin.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fedora/jellyfin.spec b/fedora/jellyfin.spec index e6a3170b56..c15b4ee957 100644 --- a/fedora/jellyfin.spec +++ b/fedora/jellyfin.spec @@ -9,8 +9,8 @@ Name: jellyfin-server Version: 10.6.0 Release: 1%{?dist} -Summary: The Free Software Media Browser -License: GPLv2 +Summary: The Free Software Media System Server backend and API +License: GPLv3 URL: https://jellyfin.media # Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` Source0: jellyfin-server-%{version}.tar.gz From 05aa28a37729e73b99cca2892b34590e456a9f07 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Tue, 24 Mar 2020 00:01:48 -0400 Subject: [PATCH 049/517] Clean up redundant Makefile steps --- fedora/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/fedora/Makefile b/fedora/Makefile index 5a76d7d944..97904ddd35 100644 --- a/fedora/Makefile +++ b/fedora/Makefile @@ -4,9 +4,6 @@ srpm: cd fedora/; \ SOURCE_DIR=.. \ WORKDIR="$${PWD}"; \ - package_temporary_dir="$${WORKDIR}/pkg-dist-tmp"; \ - pkg_src_dir="$${WORKDIR}"; \ - GNU_TAR=1; \ tar \ --transform "s,^\.,jellyfin-server-$(VERSION)," \ --exclude='.git*' \ From b9fdd96ece39a6ff0f4ff37ecba36d7a0f65fcba Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Tue, 24 Mar 2020 01:10:29 -0400 Subject: [PATCH 050/517] Remove old stuff --- deployment/old/README.md | 62 ------ deployment/old/centos-package-x64/Dockerfile | 39 ---- deployment/old/centos-package-x64/clean.sh | 32 ---- .../old/centos-package-x64/dependencies.txt | 1 - .../old/centos-package-x64/docker-build.sh | 18 -- deployment/old/centos-package-x64/package.sh | 34 ---- deployment/old/centos-package-x64/pkg-src | 1 - .../old/debian-package-arm64/Dockerfile.amd64 | 43 ----- .../old/debian-package-arm64/Dockerfile.arm64 | 34 ---- deployment/old/debian-package-arm64/clean.sh | 27 --- .../old/debian-package-arm64/dependencies.txt | 1 - .../old/debian-package-arm64/docker-build.sh | 21 -- .../old/debian-package-arm64/package.sh | 45 ----- deployment/old/debian-package-arm64/pkg-src | 1 - .../old/debian-package-armhf/Dockerfile.amd64 | 42 ---- .../old/debian-package-armhf/Dockerfile.armhf | 34 ---- deployment/old/debian-package-armhf/clean.sh | 27 --- .../old/debian-package-armhf/dependencies.txt | 1 - .../old/debian-package-armhf/docker-build.sh | 21 -- .../old/debian-package-armhf/package.sh | 45 ----- deployment/old/debian-package-armhf/pkg-src | 1 - deployment/old/debian-package-x64/Dockerfile | 34 ---- deployment/old/debian-package-x64/clean.sh | 27 --- .../old/debian-package-x64/dependencies.txt | 1 - .../old/debian-package-x64/docker-build.sh | 20 -- deployment/old/debian-package-x64/package.sh | 34 ---- .../old/debian-package-x64/pkg-src/changelog | 59 ------ .../old/debian-package-x64/pkg-src/compat | 1 - .../debian-package-x64/pkg-src/conf/jellyfin | 40 ---- .../pkg-src/conf/jellyfin-sudoers | 37 ---- .../pkg-src/conf/jellyfin.service.conf | 7 - .../pkg-src/conf/logging.json | 30 --- .../old/debian-package-x64/pkg-src/control | 31 --- .../old/debian-package-x64/pkg-src/copyright | 29 --- .../old/debian-package-x64/pkg-src/gbp.conf | 6 - .../old/debian-package-x64/pkg-src/install | 6 - .../debian-package-x64/pkg-src/jellyfin.init | 61 ------ .../pkg-src/jellyfin.service | 14 -- .../pkg-src/jellyfin.upstart | 20 -- .../debian-package-x64/pkg-src/po/POTFILES.in | 1 - .../pkg-src/po/templates.pot | 57 ------ .../old/debian-package-x64/pkg-src/postinst | 92 --------- .../old/debian-package-x64/pkg-src/postrm | 81 -------- .../old/debian-package-x64/pkg-src/preinst | 78 -------- .../old/debian-package-x64/pkg-src/prerm | 61 ------ .../old/debian-package-x64/pkg-src/rules | 66 ------- .../pkg-src/source.lintian-overrides | 3 - .../debian-package-x64/pkg-src/source/format | 1 - .../debian-package-x64/pkg-src/source/options | 11 -- deployment/old/fedora-package-x64/Dockerfile | 33 ---- deployment/old/fedora-package-x64/clean.sh | 32 ---- .../old/fedora-package-x64/dependencies.txt | 1 - .../old/fedora-package-x64/docker-build.sh | 18 -- deployment/old/fedora-package-x64/package.sh | 34 ---- .../old/fedora-package-x64/pkg-src/.gitignore | 3 - .../old/fedora-package-x64/pkg-src/README.md | 43 ----- .../pkg-src/jellyfin-firewalld.xml | 9 - .../fedora-package-x64/pkg-src/jellyfin.env | 34 ---- .../pkg-src/jellyfin.override.conf | 7 - .../pkg-src/jellyfin.service | 15 -- .../fedora-package-x64/pkg-src/jellyfin.spec | 181 ------------------ .../pkg-src/jellyfin.sudoers | 19 -- .../old/fedora-package-x64/pkg-src/restart.sh | 36 ---- deployment/old/linux-x64/Dockerfile | 37 ---- deployment/old/linux-x64/clean.sh | 27 --- deployment/old/linux-x64/dependencies.txt | 1 - deployment/old/linux-x64/docker-build.sh | 36 ---- deployment/old/linux-x64/package.sh | 34 ---- deployment/old/macos/Dockerfile | 37 ---- deployment/old/macos/clean.sh | 27 --- deployment/old/macos/dependencies.txt | 1 - deployment/old/macos/docker-build.sh | 36 ---- deployment/old/macos/package.sh | 34 ---- deployment/old/portable/Dockerfile | 37 ---- deployment/old/portable/clean.sh | 27 --- deployment/old/portable/dependencies.txt | 1 - deployment/old/portable/docker-build.sh | 36 ---- deployment/old/portable/package.sh | 34 ---- .../old/ubuntu-package-arm64/Dockerfile.amd64 | 59 ------ .../old/ubuntu-package-arm64/Dockerfile.arm64 | 40 ---- deployment/old/ubuntu-package-arm64/clean.sh | 27 --- .../old/ubuntu-package-arm64/dependencies.txt | 1 - .../old/ubuntu-package-arm64/docker-build.sh | 21 -- .../old/ubuntu-package-arm64/package.sh | 45 ----- deployment/old/ubuntu-package-arm64/pkg-src | 1 - .../old/ubuntu-package-armhf/Dockerfile.amd64 | 59 ------ .../old/ubuntu-package-armhf/Dockerfile.armhf | 40 ---- deployment/old/ubuntu-package-armhf/clean.sh | 27 --- .../old/ubuntu-package-armhf/dependencies.txt | 1 - .../old/ubuntu-package-armhf/docker-build.sh | 21 -- .../old/ubuntu-package-armhf/package.sh | 45 ----- deployment/old/ubuntu-package-armhf/pkg-src | 1 - deployment/old/ubuntu-package-x64/Dockerfile | 36 ---- deployment/old/ubuntu-package-x64/clean.sh | 27 --- .../old/ubuntu-package-x64/dependencies.txt | 1 - .../old/ubuntu-package-x64/docker-build.sh | 20 -- deployment/old/ubuntu-package-x64/package.sh | 34 ---- deployment/old/ubuntu-package-x64/pkg-src | 1 - .../old/unraid/docker-templates/README.md | 15 -- .../old/unraid/docker-templates/jellyfin.xml | 57 ------ deployment/old/win-x64/Dockerfile | 37 ---- deployment/old/win-x64/clean.sh | 27 --- deployment/old/win-x64/dependencies.txt | 1 - deployment/old/win-x64/docker-build.sh | 61 ------ deployment/old/win-x64/package.sh | 34 ---- deployment/old/win-x86/Dockerfile | 37 ---- deployment/old/win-x86/clean.sh | 27 --- deployment/old/win-x86/dependencies.txt | 1 - deployment/old/win-x86/docker-build.sh | 61 ------ deployment/old/win-x86/package.sh | 34 ---- 110 files changed, 3207 deletions(-) delete mode 100644 deployment/old/README.md delete mode 100644 deployment/old/centos-package-x64/Dockerfile delete mode 100755 deployment/old/centos-package-x64/clean.sh delete mode 100644 deployment/old/centos-package-x64/dependencies.txt delete mode 100755 deployment/old/centos-package-x64/docker-build.sh delete mode 100755 deployment/old/centos-package-x64/package.sh delete mode 120000 deployment/old/centos-package-x64/pkg-src delete mode 100644 deployment/old/debian-package-arm64/Dockerfile.amd64 delete mode 100644 deployment/old/debian-package-arm64/Dockerfile.arm64 delete mode 100755 deployment/old/debian-package-arm64/clean.sh delete mode 100644 deployment/old/debian-package-arm64/dependencies.txt delete mode 100755 deployment/old/debian-package-arm64/docker-build.sh delete mode 100755 deployment/old/debian-package-arm64/package.sh delete mode 120000 deployment/old/debian-package-arm64/pkg-src delete mode 100644 deployment/old/debian-package-armhf/Dockerfile.amd64 delete mode 100644 deployment/old/debian-package-armhf/Dockerfile.armhf delete mode 100755 deployment/old/debian-package-armhf/clean.sh delete mode 100644 deployment/old/debian-package-armhf/dependencies.txt delete mode 100755 deployment/old/debian-package-armhf/docker-build.sh delete mode 100755 deployment/old/debian-package-armhf/package.sh delete mode 120000 deployment/old/debian-package-armhf/pkg-src delete mode 100644 deployment/old/debian-package-x64/Dockerfile delete mode 100755 deployment/old/debian-package-x64/clean.sh delete mode 100644 deployment/old/debian-package-x64/dependencies.txt delete mode 100755 deployment/old/debian-package-x64/docker-build.sh delete mode 100755 deployment/old/debian-package-x64/package.sh delete mode 100644 deployment/old/debian-package-x64/pkg-src/changelog delete mode 100644 deployment/old/debian-package-x64/pkg-src/compat delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/logging.json delete mode 100644 deployment/old/debian-package-x64/pkg-src/control delete mode 100644 deployment/old/debian-package-x64/pkg-src/copyright delete mode 100644 deployment/old/debian-package-x64/pkg-src/gbp.conf delete mode 100644 deployment/old/debian-package-x64/pkg-src/install delete mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.init delete mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.service delete mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.upstart delete mode 100644 deployment/old/debian-package-x64/pkg-src/po/POTFILES.in delete mode 100644 deployment/old/debian-package-x64/pkg-src/po/templates.pot delete mode 100644 deployment/old/debian-package-x64/pkg-src/postinst delete mode 100644 deployment/old/debian-package-x64/pkg-src/postrm delete mode 100644 deployment/old/debian-package-x64/pkg-src/preinst delete mode 100644 deployment/old/debian-package-x64/pkg-src/prerm delete mode 100755 deployment/old/debian-package-x64/pkg-src/rules delete mode 100644 deployment/old/debian-package-x64/pkg-src/source.lintian-overrides delete mode 100644 deployment/old/debian-package-x64/pkg-src/source/format delete mode 100644 deployment/old/debian-package-x64/pkg-src/source/options delete mode 100644 deployment/old/fedora-package-x64/Dockerfile delete mode 100755 deployment/old/fedora-package-x64/clean.sh delete mode 100644 deployment/old/fedora-package-x64/dependencies.txt delete mode 100755 deployment/old/fedora-package-x64/docker-build.sh delete mode 100755 deployment/old/fedora-package-x64/package.sh delete mode 100644 deployment/old/fedora-package-x64/pkg-src/.gitignore delete mode 100644 deployment/old/fedora-package-x64/pkg-src/README.md delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.env delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.service delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.spec delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers delete mode 100755 deployment/old/fedora-package-x64/pkg-src/restart.sh delete mode 100644 deployment/old/linux-x64/Dockerfile delete mode 100755 deployment/old/linux-x64/clean.sh delete mode 100644 deployment/old/linux-x64/dependencies.txt delete mode 100755 deployment/old/linux-x64/docker-build.sh delete mode 100755 deployment/old/linux-x64/package.sh delete mode 100644 deployment/old/macos/Dockerfile delete mode 100755 deployment/old/macos/clean.sh delete mode 100644 deployment/old/macos/dependencies.txt delete mode 100755 deployment/old/macos/docker-build.sh delete mode 100755 deployment/old/macos/package.sh delete mode 100644 deployment/old/portable/Dockerfile delete mode 100755 deployment/old/portable/clean.sh delete mode 100644 deployment/old/portable/dependencies.txt delete mode 100755 deployment/old/portable/docker-build.sh delete mode 100755 deployment/old/portable/package.sh delete mode 100644 deployment/old/ubuntu-package-arm64/Dockerfile.amd64 delete mode 100644 deployment/old/ubuntu-package-arm64/Dockerfile.arm64 delete mode 100755 deployment/old/ubuntu-package-arm64/clean.sh delete mode 100644 deployment/old/ubuntu-package-arm64/dependencies.txt delete mode 100755 deployment/old/ubuntu-package-arm64/docker-build.sh delete mode 100755 deployment/old/ubuntu-package-arm64/package.sh delete mode 120000 deployment/old/ubuntu-package-arm64/pkg-src delete mode 100644 deployment/old/ubuntu-package-armhf/Dockerfile.amd64 delete mode 100644 deployment/old/ubuntu-package-armhf/Dockerfile.armhf delete mode 100755 deployment/old/ubuntu-package-armhf/clean.sh delete mode 100644 deployment/old/ubuntu-package-armhf/dependencies.txt delete mode 100755 deployment/old/ubuntu-package-armhf/docker-build.sh delete mode 100755 deployment/old/ubuntu-package-armhf/package.sh delete mode 120000 deployment/old/ubuntu-package-armhf/pkg-src delete mode 100644 deployment/old/ubuntu-package-x64/Dockerfile delete mode 100755 deployment/old/ubuntu-package-x64/clean.sh delete mode 100644 deployment/old/ubuntu-package-x64/dependencies.txt delete mode 100755 deployment/old/ubuntu-package-x64/docker-build.sh delete mode 100755 deployment/old/ubuntu-package-x64/package.sh delete mode 120000 deployment/old/ubuntu-package-x64/pkg-src delete mode 100644 deployment/old/unraid/docker-templates/README.md delete mode 100644 deployment/old/unraid/docker-templates/jellyfin.xml delete mode 100644 deployment/old/win-x64/Dockerfile delete mode 100755 deployment/old/win-x64/clean.sh delete mode 100644 deployment/old/win-x64/dependencies.txt delete mode 100755 deployment/old/win-x64/docker-build.sh delete mode 100755 deployment/old/win-x64/package.sh delete mode 100644 deployment/old/win-x86/Dockerfile delete mode 100755 deployment/old/win-x86/clean.sh delete mode 100644 deployment/old/win-x86/dependencies.txt delete mode 100755 deployment/old/win-x86/docker-build.sh delete mode 100755 deployment/old/win-x86/package.sh diff --git a/deployment/old/README.md b/deployment/old/README.md deleted file mode 100644 index a805f59ca3..0000000000 --- a/deployment/old/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Jellyfin Packaging - -This directory contains the packaging configuration of Jellyfin for multiple platforms. The specification is below; all package platforms must follow the specification to be compatable with the central `build` script. - -## Package List - -### Operating System Packages - -* `debian-package-x64`: Package for Debian and Ubuntu amd64 systems. -* `fedora-package-x64`: Package for Fedora, CentOS, and Red Hat Enterprise Linux amd64 systems. - -### Portable Builds (archives) - -* `linux-x64`: Portable binary archive for generic Linux amd64 systems. -* `macos`: Portable binary archive for MacOS amd64 systems. -* `win-x64`: Portable binary archive for Windows amd64 systems. -* `win-x86`: Portable binary archive for Windows i386 systems. - -### Other Builds - -These builds are not necessarily run from the `build` script, but are present for other platforms. - -* `portable`: Compiled `.dll` for use with .NET Core runtime on any system. -* `docker`: Docker manifests for auto-publishing. -* `unraid`: unRaid Docker template; not built by `build` but imported into unRaid directly. -* `windows`: Support files and scripts for Windows CI build. - -## Package Specification - -### Dependencies - -* If a platform requires additional build dependencies, the required binary names, i.e. to validate `which `, should be specified in a `dependencies.txt` file inside the platform directory. - -* Each dependency should be present on its own line. - -### Action Scripts - -* Actions are defined in BASH scripts with the name `.sh` within the platform directory. - -* The list of valid actions are: - - 1. `build`: Builds a set of binaries. - 2. `package`: Assembles the compiled binaries into a package. - 3. `sign`: Performs signing actions on a package. - 4. `publish`: Performs a publishing action for a package. - 5. `clean`: Cleans up any artifacts from the previous actions. - -* All package actions are optional, however at least one should generate output files, and any that do should contain a `clean` action. - -* Actions are executed in the order specified above, and later actions may depend on former actions. - -* Actions except for `clean` should `set -o errexit` to terminate on failed actions. - -* The `clean` action should always `exit 0` even if no work is done or it fails. - -* The `clean` action can be passed a variable as argument 1, named `keep_artifacts`, containing either the value `y` or `n`. It is indended to handle situations when the user runs `build --keep-artifacts` and should be handled intelligently. Usually, this is used to preserve Docker images while still removing temporary directories. - -### Output Files - -* Upon completion of the defined actions, at least one output file must be created in the `/pkg-dist` directory. - -* Output files will be moved to the directory `jellyfin-build/` one directory above the repository root upon completion. diff --git a/deployment/old/centos-package-x64/Dockerfile b/deployment/old/centos-package-x64/Dockerfile deleted file mode 100644 index 08219a2e4a..0000000000 --- a/deployment/old/centos-package-x64/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -FROM centos:7 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/centos-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist - -# Prepare CentOS environment -RUN yum update -y \ - && yum install -y epel-release - -# Install build dependencies -RUN yum install -y @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git - -# Install recent NodeJS and Yarn -RUN curl -fSsLo /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo \ - && rpm -i https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm \ - && yum install -y yarn - -# Install DotNET SDK -RUN rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm \ - && rpmdev-setuptree \ - && yum install -y dotnet-sdk-${SDK_VERSION} - -# Create symlinks and directories -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ - && mkdir -p ${SOURCE_DIR}/SPECS \ - && ln -s ${PLATFORM_DIR}/pkg-src/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ - && mkdir -p ${SOURCE_DIR}/SOURCES \ - && ln -s ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/SOURCES - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/centos-package-x64/clean.sh b/deployment/old/centos-package-x64/clean.sh deleted file mode 100755 index 31455de0d4..0000000000 --- a/deployment/old/centos-package-x64/clean.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" -VERSION="$( grep -A1 '^Version:' ${WORKDIR}/pkg-src/jellyfin.spec | awk '{ print $NF }' )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -package_source_dir="${WORKDIR}/pkg-src" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-centos-build" - -rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null \ - || sudo rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/centos-package-x64/dependencies.txt b/deployment/old/centos-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/centos-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/centos-package-x64/docker-build.sh b/deployment/old/centos-package-x64/docker-build.sh deleted file mode 100755 index 62dd144e50..0000000000 --- a/deployment/old/centos-package-x64/docker-build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Builds the RPM inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Build RPM -make -f .copr/Makefile srpm outdir=/root/rpmbuild/SRPMS -rpmbuild --rebuild -bb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/rpm -mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/centos-package-x64/package.sh b/deployment/old/centos-package-x64/package.sh deleted file mode 100755 index 1b983f49d9..0000000000 --- a/deployment/old/centos-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-centos-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the RPMs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the RPMs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/rpm/* "${output_dir}" diff --git a/deployment/old/centos-package-x64/pkg-src b/deployment/old/centos-package-x64/pkg-src deleted file mode 120000 index 3ff4d3cbf5..0000000000 --- a/deployment/old/centos-package-x64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../fedora-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/debian-package-arm64/Dockerfile.amd64 b/deployment/old/debian-package-arm64/Dockerfile.amd64 deleted file mode 100644 index b63e08b7dd..0000000000 --- a/deployment/old/debian-package-arm64/Dockerfile.amd64 +++ /dev/null @@ -1,43 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Prepare the cross-toolchain -RUN dpkg --add-architecture arm64 \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="arm64" cross-gcc-gensource 8 \ - && cd cross-gcc-packages-amd64/cross-gcc-8-arm64 \ - && apt-get install -y gcc-8-source libstdc++-8-dev-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 libssl-dev:arm64 liblttng-ust0:arm64 libstdc++-8-dev:arm64 - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] -#ENTRYPOINT ["/bin/bash"] diff --git a/deployment/old/debian-package-arm64/Dockerfile.arm64 b/deployment/old/debian-package-arm64/Dockerfile.arm64 deleted file mode 100644 index 9ca4868441..0000000000 --- a/deployment/old/debian-package-arm64/Dockerfile.arm64 +++ /dev/null @@ -1,34 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=arm64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/5a4c8f96-1c73-401c-a6de-8e100403188a/0ce6ab39747e2508366d498f9c0a0669/dotnet-sdk-3.1.100-linux-arm64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-arm64/clean.sh b/deployment/old/debian-package-arm64/clean.sh deleted file mode 100755 index e7bfdf8b4b..0000000000 --- a/deployment/old/debian-package-arm64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_arm64-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/debian-package-arm64/dependencies.txt b/deployment/old/debian-package-arm64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/debian-package-arm64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/debian-package-arm64/docker-build.sh b/deployment/old/debian-package-arm64/docker-build.sh deleted file mode 100755 index 67ab6bd74b..0000000000 --- a/deployment/old/debian-package-arm64/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarm64 - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-arm64/package.sh b/deployment/old/debian-package-arm64/package.sh deleted file mode 100755 index 2091982187..0000000000 --- a/deployment/old/debian-package-arm64/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_arm64-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.arm64" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-arm64/pkg-src b/deployment/old/debian-package-arm64/pkg-src deleted file mode 120000 index 4c695fea17..0000000000 --- a/deployment/old/debian-package-arm64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/debian-package-armhf/Dockerfile.amd64 b/deployment/old/debian-package-armhf/Dockerfile.amd64 deleted file mode 100644 index 1b64b53148..0000000000 --- a/deployment/old/debian-package-armhf/Dockerfile.amd64 +++ /dev/null @@ -1,42 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Prepare the cross-toolchain -RUN dpkg --add-architecture armhf \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="armhf" cross-gcc-gensource 8 \ - && cd cross-gcc-packages-amd64/cross-gcc-8-armhf \ - && apt-get install -y gcc-8-source libstdc++-8-dev-armhf-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip binutils-arm-linux-gnueabihf libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf liblttng-ust0:armhf libstdc++-8-dev:armhf - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-armhf/Dockerfile.armhf b/deployment/old/debian-package-armhf/Dockerfile.armhf deleted file mode 100644 index dd398b5aa5..0000000000 --- a/deployment/old/debian-package-armhf/Dockerfile.armhf +++ /dev/null @@ -1,34 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=armhf - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/67766a96-eb8c-4cd2-bca4-ea63d2cc115c/7bf13840aa2ed88793b7315d5e0d74e6/dotnet-sdk-3.1.100-linux-arm.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-armhf/clean.sh b/deployment/old/debian-package-armhf/clean.sh deleted file mode 100755 index 35a3d3e9ad..0000000000 --- a/deployment/old/debian-package-armhf/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_armhf-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/debian-package-armhf/dependencies.txt b/deployment/old/debian-package-armhf/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/debian-package-armhf/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/debian-package-armhf/docker-build.sh b/deployment/old/debian-package-armhf/docker-build.sh deleted file mode 100755 index 1bd7fb2911..0000000000 --- a/deployment/old/debian-package-armhf/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarmhf - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-armhf/package.sh b/deployment/old/debian-package-armhf/package.sh deleted file mode 100755 index 4a27dd8283..0000000000 --- a/deployment/old/debian-package-armhf/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_armhf-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.armhf" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-armhf/pkg-src b/deployment/old/debian-package-armhf/pkg-src deleted file mode 120000 index 0bb6d55249..0000000000 --- a/deployment/old/debian-package-armhf/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/debian-package-x64/Dockerfile b/deployment/old/debian-package-x64/Dockerfile deleted file mode 100644 index e863d1edf9..0000000000 --- a/deployment/old/debian-package-x64/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-x64/clean.sh b/deployment/old/debian-package-x64/clean.sh deleted file mode 100755 index 4e507bcb27..0000000000 --- a/deployment/old/debian-package-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/debian-package-x64/dependencies.txt b/deployment/old/debian-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/debian-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/debian-package-x64/docker-build.sh b/deployment/old/debian-package-x64/docker-build.sh deleted file mode 100755 index 962a522ebc..0000000000 --- a/deployment/old/debian-package-x64/docker-build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -dpkg-buildpackage -us -uc - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-x64/package.sh b/deployment/old/debian-package-x64/package.sh deleted file mode 100755 index 5a416959ab..0000000000 --- a/deployment/old/debian-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-x64/pkg-src/changelog b/deployment/old/debian-package-x64/pkg-src/changelog deleted file mode 100644 index 51c4822370..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/changelog +++ /dev/null @@ -1,59 +0,0 @@ -jellyfin (10.5.0-1) unstable; urgency=medium - - * New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 - - -- Jellyfin Packaging Team Fri, 11 Oct 2019 20:12:38 -0400 - -jellyfin (10.4.0-1) unstable; urgency=medium - - * New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 - - -- Jellyfin Packaging Team Sat, 31 Aug 2019 21:38:56 -0400 - -jellyfin (10.3.7-1) unstable; urgency=medium - - * New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 - - -- Jellyfin Packaging Team Wed, 24 Jul 2019 10:48:28 -0400 - -jellyfin (10.3.6-1) unstable; urgency=medium - - * New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 - - -- Jellyfin Packaging Team Sat, 06 Jul 2019 13:34:19 -0400 - -jellyfin (10.3.5-1) unstable; urgency=medium - - * New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 - - -- Jellyfin Packaging Team Sun, 09 Jun 2019 21:47:35 -0400 - -jellyfin (10.3.4-1) unstable; urgency=medium - - * New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 - - -- Jellyfin Packaging Team Thu, 06 Jun 2019 22:45:31 -0400 - -jellyfin (10.3.3-1) unstable; urgency=medium - - * New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 - - -- Jellyfin Packaging Team Fri, 17 May 2019 23:12:08 -0400 - -jellyfin (10.3.2-1) unstable; urgency=medium - - * New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 - - -- Jellyfin Packaging Team Tue, 30 Apr 2019 20:18:44 -0400 - -jellyfin (10.3.1-1) unstable; urgency=medium - - * New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 - - -- Jellyfin Packaging Team Sat, 20 Apr 2019 14:24:07 -0400 - -jellyfin (10.3.0-1) unstable; urgency=medium - - * New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 - - -- Jellyfin Packaging Team Fri, 19 Apr 2019 14:24:29 -0400 diff --git a/deployment/old/debian-package-x64/pkg-src/compat b/deployment/old/debian-package-x64/pkg-src/compat deleted file mode 100644 index 45a4fb75db..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/compat +++ /dev/null @@ -1 +0,0 @@ -8 diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin deleted file mode 100644 index c6e595f15a..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin +++ /dev/null @@ -1,40 +0,0 @@ -# Jellyfin default configuration options -# This is a POSIX shell fragment - -# Use this file to override the default configurations; add additional -# options with JELLYFIN_ADD_OPTS. - -# Under systemd, use -# /etc/systemd/system/jellyfin.service.d/jellyfin.service.conf -# to override the user or this config file's location. - -# -# General options -# - -# Program directories -JELLYFIN_DATA_DIR="/var/lib/jellyfin" -JELLYFIN_CONFIG_DIR="/etc/jellyfin" -JELLYFIN_LOG_DIR="/var/log/jellyfin" -JELLYFIN_CACHE_DIR="/var/cache/jellyfin" - -# Restart script for in-app server control -JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh" - -# ffmpeg binary paths, overriding the system values -JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/lib/jellyfin-ffmpeg/ffmpeg" - -# [OPTIONAL] run Jellyfin as a headless service -#JELLYFIN_SERVICE_OPT="--service" - -# [OPTIONAL] run Jellyfin without the web app -#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" - -# -# SysV init/Upstart options -# - -# Application username -JELLYFIN_USER="jellyfin" -# Full application command -JELLYFIN_ARGS="$JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLFIN_NOWEBAPP_OPT" diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers deleted file mode 100644 index b481ba4ad4..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers +++ /dev/null @@ -1,37 +0,0 @@ -#Allow jellyfin group to start, stop and restart itself -Cmnd_Alias RESTARTSERVER_SYSV = /sbin/service jellyfin restart, /usr/sbin/service jellyfin restart -Cmnd_Alias STARTSERVER_SYSV = /sbin/service jellyfin start, /usr/sbin/service jellyfin start -Cmnd_Alias STOPSERVER_SYSV = /sbin/service jellyfin stop, /usr/sbin/service jellyfin stop -Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin -Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin -Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin -Cmnd_Alias RESTARTSERVER_INITD = /etc/init.d/jellyfin restart -Cmnd_Alias STARTSERVER_INITD = /etc/init.d/jellyfin start -Cmnd_Alias STOPSERVER_INITD = /etc/init.d/jellyfin stop - - -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSV -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSV -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSV -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_INITD -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_INITD -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_INITD - -Defaults!RESTARTSERVER_SYSV !requiretty -Defaults!STARTSERVER_SYSV !requiretty -Defaults!STOPSERVER_SYSV !requiretty -Defaults!RESTARTSERVER_SYSTEMD !requiretty -Defaults!STARTSERVER_SYSTEMD !requiretty -Defaults!STOPSERVER_SYSTEMD !requiretty -Defaults!RESTARTSERVER_INITD !requiretty -Defaults!STARTSERVER_INITD !requiretty -Defaults!STOPSERVER_INITD !requiretty - -#Allow the server to mount iso images -jellyfin ALL=(ALL) NOPASSWD: /bin/mount -jellyfin ALL=(ALL) NOPASSWD: /bin/umount - -Defaults:jellyfin !requiretty diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf deleted file mode 100644 index 1b69dd74ef..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf +++ /dev/null @@ -1,7 +0,0 @@ -# Jellyfin systemd configuration options - -# Use this file to override the user or environment file location. - -[Service] -#User = jellyfin -#EnvironmentFile = /etc/default/jellyfin diff --git a/deployment/old/debian-package-x64/pkg-src/conf/logging.json b/deployment/old/debian-package-x64/pkg-src/conf/logging.json deleted file mode 100644 index f32b2089eb..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/logging.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "Serilog": { - "MinimumLevel": "Information", - "WriteTo": [ - { - "Name": "Console", - "Args": { - "outputTemplate": "[{Timestamp:HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "Async", - "Args": { - "configure": [ - { - "Name": "File", - "Args": { - "path": "%JELLYFIN_LOG_DIR%//jellyfin.log", - "fileSizeLimitBytes": 10485700, - "rollOnFileSizeLimit": true, - "retainedFileCountLimit": 10, - "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] {Message}{NewLine}{Exception}" - } - } - ] - } - } - ] - } -} diff --git a/deployment/old/debian-package-x64/pkg-src/control b/deployment/old/debian-package-x64/pkg-src/control deleted file mode 100644 index 13fd3ecabb..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/control +++ /dev/null @@ -1,31 +0,0 @@ -Source: jellyfin -Section: misc -Priority: optional -Maintainer: Jellyfin Team -Build-Depends: debhelper (>= 9), - dotnet-sdk-3.1, - libc6-dev, - libcurl4-openssl-dev, - libfontconfig1-dev, - libfreetype6-dev, - libssl-dev, - wget, - npm | nodejs -Standards-Version: 3.9.4 -Homepage: https://jellyfin.media/ -Vcs-Git: https://github.org/jellyfin/jellyfin.git -Vcs-Browser: https://github.org/jellyfin/jellyfin - -Package: jellyfin -Replaces: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server -Breaks: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server -Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server -Architecture: any -Depends: at, - libsqlite3-0, - jellyfin-ffmpeg, - libfontconfig1, - libfreetype6, - libssl1.1 -Description: Jellyfin is a home media server. - It is built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono. It features a REST-based api with built-in documentation to facilitate client development. We also have client libraries for our api to enable rapid development. diff --git a/deployment/old/debian-package-x64/pkg-src/copyright b/deployment/old/debian-package-x64/pkg-src/copyright deleted file mode 100644 index 0d7a2a6007..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/copyright +++ /dev/null @@ -1,29 +0,0 @@ -Format: http://dep.debian.net/deps/dep5 -Upstream-Name: jellyfin -Source: https://github.com/jellyfin/jellyfin - -Files: * -Copyright: 2018 Jellyfin Team -License: GPL-2.0+ - -Files: debian/* -Copyright: 2018 Joshua Boniface -Copyright: 2014 Carlos Hernandez -License: GPL-2.0+ - -License: GPL-2.0+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see - . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/deployment/old/debian-package-x64/pkg-src/gbp.conf b/deployment/old/debian-package-x64/pkg-src/gbp.conf deleted file mode 100644 index 60b3d28723..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/gbp.conf +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -pristine-tar = False -cleaner = fakeroot debian/rules clean - -[import-orig] -filter = [ ".git*", ".hg*", ".vs*", ".vscode*" ] diff --git a/deployment/old/debian-package-x64/pkg-src/install b/deployment/old/debian-package-x64/pkg-src/install deleted file mode 100644 index 994322d141..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/install +++ /dev/null @@ -1,6 +0,0 @@ -usr/lib/jellyfin usr/lib/ -debian/conf/jellyfin etc/default/ -debian/conf/logging.json etc/jellyfin/ -debian/conf/jellyfin.service.conf etc/systemd/system/jellyfin.service.d/ -debian/conf/jellyfin-sudoers etc/sudoers.d/ -debian/bin/restart.sh usr/lib/jellyfin/ diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.init b/deployment/old/debian-package-x64/pkg-src/jellyfin.init deleted file mode 100644 index 7f5642bac1..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/jellyfin.init +++ /dev/null @@ -1,61 +0,0 @@ -### BEGIN INIT INFO -# Provides: Jellyfin Media Server -# Required-Start: $local_fs $network -# Required-Stop: $local_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Jellyfin Media Server -# Description: Runs Jellyfin Server -### END INIT INFO - -set -e - -# Carry out specific functions when asked to by the system - -if test -f /etc/default/jellyfin; then - . /etc/default/jellyfin -fi - -. /lib/lsb/init-functions - -PIDFILE="/run/jellyfin.pid" - -case "$1" in - start) - log_daemon_msg "Starting Jellyfin Media Server" "jellyfin" || true - - if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then - log_end_msg 0 || true - else - log_end_msg 1 || true - fi - ;; - - stop) - log_daemon_msg "Stopping Jellyfin Media Server" "jellyfin" || true - if start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --remove-pidfile; then - log_end_msg 0 || true - else - log_end_msg 1 || true - fi - ;; - - restart) - log_daemon_msg "Restarting Jellyfin Media Server" "jellyfin" || true - start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE --remove-pidfile - if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then - log_end_msg 0 || true - else - log_end_msg 1 || true - fi - ;; - - status) - status_of_proc -p $PIDFILE /usr/bin/jellyfin jellyfin && exit 0 || exit $? - ;; - - *) - echo "Usage: $0 {start|stop|restart|status}" - exit 1 - ;; -esac diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.service b/deployment/old/debian-package-x64/pkg-src/jellyfin.service deleted file mode 100644 index 1305e238b0..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/jellyfin.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description = Jellyfin Media Server -After = network.target - -[Service] -Type = simple -EnvironmentFile = /etc/default/jellyfin -User = jellyfin -ExecStart = /usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} -Restart = on-failure -TimeoutSec = 15 - -[Install] -WantedBy = multi-user.target diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart b/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart deleted file mode 100644 index ef5bc9bcaf..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart +++ /dev/null @@ -1,20 +0,0 @@ -description "jellyfin daemon" - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on runlevel [!2345] - -console log -respawn -respawn limit 10 5 - -kill timeout 20 - -script - set -x - echo "Starting $UPSTART_JOB" - - # Log file - logger -t "$0" "DEBUG: `set`" - . /etc/default/jellyfin - exec su -u $JELLYFIN_USER -c /usr/bin/jellyfin $JELLYFIN_ARGS -end script diff --git a/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in b/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in deleted file mode 100644 index cef83a3407..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in +++ /dev/null @@ -1 +0,0 @@ -[type: gettext/rfc822deb] templates diff --git a/deployment/old/debian-package-x64/pkg-src/po/templates.pot b/deployment/old/debian-package-x64/pkg-src/po/templates.pot deleted file mode 100644 index 2cdcae4173..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/po/templates.pot +++ /dev/null @@ -1,57 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: jellyfin-server\n" -"Report-Msgid-Bugs-To: jellyfin-server@packages.debian.org\n" -"POT-Creation-Date: 2015-06-12 20:51-0600\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: note -#. Description -#: ../templates:1001 -msgid "Jellyfin permission info:" -msgstr "" - -#. Type: note -#. Description -#: ../templates:1001 -msgid "" -"Jellyfin by default runs under a user named \"jellyfin\". Please ensure that the " -"user jellyfin has read and write access to any folders you wish to add to your " -"library. Otherwise please run jellyfin under a different user." -msgstr "" - -#. Type: string -#. Description -#: ../templates:2001 -msgid "Username to run Jellyfin as:" -msgstr "" - -#. Type: string -#. Description -#: ../templates:2001 -msgid "The user that jellyfin will run as." -msgstr "" - -#. Type: note -#. Description -#: ../templates:3001 -msgid "Jellyfin still running" -msgstr "" - -#. Type: note -#. Description -#: ../templates:3001 -msgid "Jellyfin is currently running. Please close it and try again." -msgstr "" diff --git a/deployment/old/debian-package-x64/pkg-src/postinst b/deployment/old/debian-package-x64/pkg-src/postinst deleted file mode 100644 index 860222e051..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/postinst +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -case "$1" in - configure) - # create jellyfin group if it does not exist - if [[ -z "$(getent group jellyfin)" ]]; then - addgroup --quiet --system jellyfin > /dev/null 2>&1 - fi - # create jellyfin user if it does not exist - if [[ -z "$(getent passwd jellyfin)" ]]; then - adduser --system --ingroup jellyfin --shell /bin/false jellyfin --no-create-home --home ${PROGRAMDATA} \ - --gecos "Jellyfin default user" > /dev/null 2>&1 - fi - # ensure $PROGRAMDATA exists - if [[ ! -d $PROGRAMDATA ]]; then - mkdir $PROGRAMDATA - fi - # ensure $CONFIGDATA exists - if [[ ! -d $CONFIGDATA ]]; then - mkdir $CONFIGDATA - fi - # ensure $LOGDATA exists - if [[ ! -d $LOGDATA ]]; then - mkdir $LOGDATA - fi - # ensure $CACHEDATA exists - if [[ ! -d $CACHEDATA ]]; then - mkdir $CACHEDATA - fi - # Ensure permissions are correct on all config directories - chown -R jellyfin $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA - chgrp adm $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA - chmod 0750 $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA - - chmod +x /usr/lib/jellyfin/restart.sh > /dev/null 2>&1 || true - - # Install jellyfin symlink into /usr/bin - ln -sf /usr/lib/jellyfin/bin/jellyfin /usr/bin/jellyfin - - ;; - abort-upgrade|abort-remove|abort-deconfigure) - ;; - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER - -if [[ -x "/usr/bin/deb-systemd-helper" ]]; then - # Manual init script handling - deb-systemd-helper unmask jellyfin.service >/dev/null || true - # was-enabled defaults to true, so new installations run enable. - if deb-systemd-helper --quiet was-enabled jellyfin.service; then - # Enables the unit on first installation, creates new - # symlinks on upgrades if the unit file has changed. - deb-systemd-helper enable jellyfin.service >/dev/null || true - else - # Update the statefile to add new symlinks (if any), which need to be - # cleaned up on purge. Also remove old symlinks. - deb-systemd-helper update-state jellyfin.service >/dev/null || true - fi -fi - -# End automatically added section -# Automatically added by dh_installinit -if [[ "$1" == "configure" ]] || [[ "$1" == "abort-upgrade" ]]; then - if [[ -d "/run/systemd/systemd" ]]; then - systemctl --system daemon-reload >/dev/null || true - deb-systemd-invoke start jellyfin >/dev/null || true - elif [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.conf" ]]; then - update-rc.d jellyfin defaults >/dev/null - invoke-rc.d jellyfin start || exit $? - fi -fi -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/postrm b/deployment/old/debian-package-x64/pkg-src/postrm deleted file mode 100644 index 1d00a984ec..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/postrm +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -# In case this system is running systemd, we make systemd reload the unit files -# to pick up changes. -if [[ -d /run/systemd/system ]] ; then - systemctl --system daemon-reload >/dev/null || true -fi - -case "$1" in - purge) - echo PURGE | debconf-communicate $NAME > /dev/null 2>&1 || true - - if [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.connf" ]]; then - update-rc.d jellyfin remove >/dev/null 2>&1 || true - fi - - if [[ -x "/usr/bin/deb-systemd-helper" ]]; then - deb-systemd-helper purge jellyfin.service >/dev/null - deb-systemd-helper unmask jellyfin.service >/dev/null - fi - - # Remove user and group - userdel jellyfin > /dev/null 2>&1 || true - delgroup --quiet jellyfin > /dev/null 2>&1 || true - # Remove config dir - if [[ -d $CONFIGDATA ]]; then - rm -rf $CONFIGDATA - fi - # Remove log dir - if [[ -d $LOGDATA ]]; then - rm -rf $LOGDATA - fi - # Remove cache dir - if [[ -d $CACHEDATA ]]; then - rm -rf $CACHEDATA - fi - # Remove program data dir - if [[ -d $PROGRAMDATA ]]; then - rm -rf $PROGRAMDATA - fi - # Remove binary symlink - [[ -f /usr/bin/jellyfin ]] && rm /usr/bin/jellyfin - # Remove sudoers config - [[ -f /etc/sudoers.d/jellyfin-sudoers ]] && rm /etc/sudoers.d/jellyfin-sudoers - # Remove anything at the default locations; catches situations where the user moved the defaults - [[ -e /etc/jellyfin ]] && rm -rf /etc/jellyfin - [[ -e /var/log/jellyfin ]] && rm -rf /var/log/jellyfin - [[ -e /var/cache/jellyfin ]] && rm -rf /var/cache/jellyfin - [[ -e /var/lib/jellyfin ]] && rm -rf /var/lib/jellyfin - ;; - remove) - if [[ -x "/usr/bin/deb-systemd-helper" ]]; then - deb-systemd-helper mask jellyfin.service >/dev/null - fi - ;; - upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/preinst b/deployment/old/debian-package-x64/pkg-src/preinst deleted file mode 100644 index 2713fb9b80..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/preinst +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -# In case this system is running systemd, we make systemd reload the unit files -# to pick up changes. -if [[ -d /run/systemd/system ]] ; then - systemctl --system daemon-reload >/dev/null || true -fi - -case "$1" in - install|upgrade) - # try graceful termination; - if [[ -d /run/systemd/system ]]; then - deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true - elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then - invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true - fi - # try and figure out if jellyfin is running - PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) - [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) - # if its running, let's stop it - if [[ -n "$JELLYFIN_PID" ]]; then - echo "Stopping Jellyfin!" - # if jellyfin is still running, kill it - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - CPIDS=$(pgrep -P $JELLYFIN_PID) - sleep 2 && kill -KILL $CPIDS - kill -TERM $CPIDS > /dev/null 2>&1 - fi - sleep 1 - # if it's still running, show error - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - echo "Could not successfully stop JellyfinServer, please do so before uninstalling." - exit 1 - else - [[ -f $PIDFILE ]] && rm $PIDFILE - fi - fi - - # Clean up old Emby cruft that can break the user's system - [[ -f /etc/sudoers.d/emby ]] && rm -f /etc/sudoers.d/emby - - # If we have existing config, log, or cache dirs in /var/lib/jellyfin, move them into the right place - if [[ -d $PROGRAMDATA/config ]]; then - mv $PROGRAMDATA/config $CONFIGDATA - fi - if [[ -d $PROGRAMDATA/logs ]]; then - mv $PROGRAMDATA/logs $LOGDATA - fi - if [[ -d $PROGRAMDATA/logs ]]; then - mv $PROGRAMDATA/cache $CACHEDATA - fi - - ;; - abort-upgrade) - ;; - *) - echo "preinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac -#DEBHELPER# - -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/prerm b/deployment/old/debian-package-x64/pkg-src/prerm deleted file mode 100644 index e965cb7d71..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/prerm +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -case "$1" in - remove|upgrade|deconfigure) - echo "Stopping Jellyfin!" - # try graceful termination; - if [[ -d /run/systemd/system ]]; then - deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true - elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then - invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true - fi - # Ensure that it is shutdown - PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) - [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) - # if its running, let's stop it - if [[ -n "$JELLYFIN_PID" ]]; then - # if jellyfin is still running, kill it - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - CPIDS=$(pgrep -P $JELLYFIN_PID) - sleep 2 && kill -KILL $CPIDS - kill -TERM $CPIDS > /dev/null 2>&1 - fi - sleep 1 - # if it's still running, show error - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - echo "Could not successfully stop Jellyfin, please do so before uninstalling." - exit 1 - else - [[ -f $PIDFILE ]] && rm $PIDFILE - fi - fi - if [[ -f /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so ]]; then - rm /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so - fi - ;; - failed-upgrade) - ;; - *) - echo "prerm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/rules b/deployment/old/debian-package-x64/pkg-src/rules deleted file mode 100755 index c2d57dfb22..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/rules +++ /dev/null @@ -1,66 +0,0 @@ -#! /usr/bin/make -f -CONFIG := Release -TERM := xterm -SHELL := /bin/bash -WEB_TARGET := $(CURDIR)/MediaBrowser.WebDashboard/jellyfin-web -WEB_VERSION := $(shell sed -n -e 's/^version: "\(.*\)"/\1/p' $(CURDIR)/build.yaml) - -HOST_ARCH := $(shell arch) -BUILD_ARCH := ${DEB_HOST_MULTIARCH} -ifeq ($(HOST_ARCH),x86_64) - # Building AMD64 - DOTNETRUNTIME := debian-x64 - ifeq ($(BUILD_ARCH),arm-linux-gnueabihf) - # Cross-building ARM on AMD64 - DOTNETRUNTIME := debian-arm - endif - ifeq ($(BUILD_ARCH),aarch64-linux-gnu) - # Cross-building ARM on AMD64 - DOTNETRUNTIME := debian-arm64 - endif -endif -ifeq ($(HOST_ARCH),armv7l) - # Building ARM - DOTNETRUNTIME := debian-arm -endif -ifeq ($(HOST_ARCH),arm64) - # Building ARM - DOTNETRUNTIME := debian-arm64 -endif - -export DH_VERBOSE=1 -export DOTNET_CLI_TELEMETRY_OPTOUT=1 - -%: - dh $@ - -# disable "make check" -override_dh_auto_test: - -# disable stripping debugging symbols -override_dh_clistrip: - -override_dh_auto_build: - echo $(WEB_VERSION) - # Clone down and build Web frontend - mkdir -p $(WEB_TARGET) - wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/v$(WEB_VERSION).tar.gz || wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/master.tar.gz - mkdir -p $(CURDIR)/web - tar -xzf web-src.tgz -C $(CURDIR)/web/ --strip 1 - cd $(CURDIR)/web/ && npm install yarn - cd $(CURDIR)/web/ && node_modules/yarn/bin/yarn install - mv $(CURDIR)/web/dist/* $(WEB_TARGET)/ - # Build the application - dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) \ - "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server - -override_dh_auto_clean: - dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true - rm -f '$(CURDIR)/web-src.tgz' - rm -rf '$(CURDIR)/usr' - rm -rf '$(CURDIR)/web' - rm -rf '$(WEB_TARGET)' - -# Force the service name to jellyfin even if we're building jellyfin-nightly -override_dh_installinit: - dh_installinit --name=jellyfin diff --git a/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides b/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides deleted file mode 100644 index aeb332f13a..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides +++ /dev/null @@ -1,3 +0,0 @@ -# This is an override for the following lintian errors: -jellyfin source: license-problem-md5sum-non-free-file Emby.Drawing/ImageMagick/fonts/webdings.ttf* -jellyfin source: source-is-missing diff --git a/deployment/old/debian-package-x64/pkg-src/source/format b/deployment/old/debian-package-x64/pkg-src/source/format deleted file mode 100644 index d3827e75a5..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/source/format +++ /dev/null @@ -1 +0,0 @@ -1.0 diff --git a/deployment/old/debian-package-x64/pkg-src/source/options b/deployment/old/debian-package-x64/pkg-src/source/options deleted file mode 100644 index 17b5373d5e..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/source/options +++ /dev/null @@ -1,11 +0,0 @@ -tar-ignore='.git*' -tar-ignore='**/.git' -tar-ignore='**/.hg' -tar-ignore='**/.vs' -tar-ignore='**/.vscode' -tar-ignore='deployment' -tar-ignore='**/bin' -tar-ignore='**/obj' -tar-ignore='**/.nuget' -tar-ignore='*.deb' -tar-ignore='ThirdParty' diff --git a/deployment/old/fedora-package-x64/Dockerfile b/deployment/old/fedora-package-x64/Dockerfile deleted file mode 100644 index 87120f3a05..0000000000 --- a/deployment/old/fedora-package-x64/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM fedora:31 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/fedora-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist - -# Prepare Fedora environment -RUN dnf update -y - -# Install build dependencies -RUN dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel nodejs-yarn - -# Install DotNET SDK -RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc \ - && curl -o /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/$(rpm -E %fedora)/prod.repo \ - && dnf install -y dotnet-sdk-${SDK_VERSION} dotnet-runtime-${SDK_VERSION} - -# Create symlinks and directories -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ - && mkdir -p ${SOURCE_DIR}/SPECS \ - && ln -s ${PLATFORM_DIR}/pkg-src/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ - && mkdir -p ${SOURCE_DIR}/SOURCES \ - && ln -s ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/SOURCES - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/fedora-package-x64/clean.sh b/deployment/old/fedora-package-x64/clean.sh deleted file mode 100755 index 700c8f1bb3..0000000000 --- a/deployment/old/fedora-package-x64/clean.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" -VERSION="$( grep -A1 '^Version:' ${WORKDIR}/pkg-src/jellyfin.spec | awk '{ print $NF }' )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -package_source_dir="${WORKDIR}/pkg-src" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-fedora-build" - -rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null \ - || sudo rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/fedora-package-x64/dependencies.txt b/deployment/old/fedora-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/fedora-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/fedora-package-x64/docker-build.sh b/deployment/old/fedora-package-x64/docker-build.sh deleted file mode 100755 index 740e8d35ca..0000000000 --- a/deployment/old/fedora-package-x64/docker-build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Builds the RPM inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Build RPM -make -f .copr/Makefile srpm outdir=/root/rpmbuild/SRPMS -rpmbuild -rb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/rpm -mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/fedora-package-x64/package.sh b/deployment/old/fedora-package-x64/package.sh deleted file mode 100755 index ae6962dd1f..0000000000 --- a/deployment/old/fedora-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-fedora-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the RPMs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the RPMs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/rpm/* "${output_dir}" diff --git a/deployment/old/fedora-package-x64/pkg-src/.gitignore b/deployment/old/fedora-package-x64/pkg-src/.gitignore deleted file mode 100644 index 6019b98c22..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.rpm -*.zip -*.tar.gz \ No newline at end of file diff --git a/deployment/old/fedora-package-x64/pkg-src/README.md b/deployment/old/fedora-package-x64/pkg-src/README.md deleted file mode 100644 index 7ed6f7efc6..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Jellyfin RPM - -## Build Fedora Package with docker - -Change into this directory `cd rpm-package` -Run the build script `./build-fedora-rpm.sh`. -Resulting RPM and src.rpm will be in `../../jellyfin-*.rpm` - -## ffmpeg - -The RPM package for Fedora/CentOS requires some additional repositories as ffmpeg is not in the main repositories. - -```shell -# ffmpeg from RPMfusion free -# Fedora -$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm -# CentOS 7 -$ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm -``` - -## ISO mounting - -To allow Jellyfin to mount/umount ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` -``` -# %jellyfin ALL=(ALL) NOPASSWD: /bin/mount -# %jellyfin ALL=(ALL) NOPASSWD: /bin/umount -``` - -## Building with dotnet - -Jellyfin is build with `--self-contained` so no dotnet required for runtime. - -```shell -# dotnet required for building the RPM -# Fedora -$ sudo dnf copr enable @dotnet-sig/dotnet -# CentOS -$ sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm -``` - -## TODO - -- [ ] OpenSUSE \ No newline at end of file diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml b/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml deleted file mode 100644 index 538c5d65f8..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - Jellyfin - The Free Software Media System. - - - - - diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.env b/deployment/old/fedora-package-x64/pkg-src/jellyfin.env deleted file mode 100644 index de48f13af5..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.env +++ /dev/null @@ -1,34 +0,0 @@ -# Jellyfin default configuration options - -# Use this file to override the default configurations; add additional -# options with JELLYFIN_ADD_OPTS. - -# To override the user or this config file's location, use -# /etc/systemd/system/jellyfin.service.d/override.conf - -# -# This is a POSIX shell fragment -# - -# -# General options -# - -# Program directories -JELLYFIN_DATA_DIR="/var/lib/jellyfin" -JELLYFIN_CONFIG_DIR="/etc/jellyfin" -JELLYFIN_LOG_DIR="/var/log/jellyfin" -JELLYFIN_CACHE_DIR="/var/cache/jellyfin" - -# In-App service control -JELLYFIN_RESTART_OPT="--restartpath=/usr/libexec/jellyfin/restart.sh" - -# [OPTIONAL] ffmpeg binary paths, overriding the UI-configured values -#JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/bin/ffmpeg" - -# [OPTIONAL] run Jellyfin as a headless service -#JELLYFIN_SERVICE_OPT="--service" - -# [OPTIONAL] run Jellyfin without the web app -#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" - diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf b/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf deleted file mode 100644 index 8652450bb4..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf +++ /dev/null @@ -1,7 +0,0 @@ -# Jellyfin systemd configuration options - -# Use this file to override the user or environment file location. - -[Service] -#User = jellyfin -#EnvironmentFile = /etc/sysconfig/jellyfin diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.service b/deployment/old/fedora-package-x64/pkg-src/jellyfin.service deleted file mode 100644 index f3dc594b1c..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -After=network.target -Description=Jellyfin is a free software media system that puts you in control of managing and streaming your media. - -[Service] -EnvironmentFile=/etc/sysconfig/jellyfin -WorkingDirectory=/var/lib/jellyfin -ExecStart=/usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} -TimeoutSec=15 -Restart=on-failure -User=jellyfin -Group=jellyfin - -[Install] -WantedBy=multi-user.target diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec deleted file mode 100644 index 33c6f6f648..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec +++ /dev/null @@ -1,181 +0,0 @@ -%global debug_package %{nil} -# Set the dotnet runtime -%if 0%{?fedora} -%global dotnet_runtime fedora-x64 -%else -%global dotnet_runtime centos-x64 -%endif - -Name: jellyfin -Version: 10.5.0 -Release: 1%{?dist} -Summary: The Free Software Media Browser -License: GPLv2 -URL: https://jellyfin.media -# Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` -Source0: https://github.com/%{name}/%{name}/archive/%{name}-%{version}.tar.gz -# Jellyfin Webinterface downloaded by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` -Source1: https://github.com/%{name}/%{name}-web/archive/%{name}-web-%{version}.tar.gz -Source11: jellyfin.service -Source12: jellyfin.env -Source13: jellyfin.sudoers -Source14: restart.sh -Source15: jellyfin.override.conf -Source16: jellyfin-firewalld.xml - -%{?systemd_requires} -BuildRequires: systemd -Requires(pre): shadow-utils -BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel, git -%if 0%{?fedora} -BuildRequires: nodejs-yarn, git -%else -# Requirements not packaged in main repos -# From https://rpm.nodesource.com/pub_10.x/el/7/x86_64/ -BuildRequires: nodejs >= 10 yarn -%endif -Requires: libcurl, fontconfig, freetype, openssl, glibc libicu -# Requirements not packaged in main repos -# COPR @dotnet-sig/dotnet or -# https://packages.microsoft.com/rhel/7/prod/ -BuildRequires: dotnet-runtime-3.1, dotnet-sdk-3.1 -# RPMfusion free -Requires: ffmpeg - -# Disable Automatic Dependency Processing -AutoReqProv: no - -%description -Jellyfin is a free software media system that puts you in control of managing and streaming your media. - - -%prep -%autosetup -n %{name}-%{version} -b 0 -b 1 -web_build_dir="$(mktemp -d)" -web_target="$PWD/MediaBrowser.WebDashboard/jellyfin-web" -pushd ../jellyfin-web-%{version} || pushd ../jellyfin-web-master -%if 0%{?fedora} -nodejs-yarn install -%else -yarn install -%endif -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd - -%build - -%install -export DOTNET_CLI_TELEMETRY_OPTOUT=1 -export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime %{dotnet_runtime} \ - "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server -%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE -%{__install} -D -m 0644 %{SOURCE15} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf -%{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json -%{__mkdir} -p %{buildroot}%{_bindir} -tee %{buildroot}%{_bindir}/jellyfin << EOF -#!/bin/sh -exec %{_libdir}/%{name}/%{name} \${@} -EOF -%{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin -%{__mkdir} -p %{buildroot}%{_sysconfdir}/%{name} -%{__mkdir} -p %{buildroot}%{_var}/log/jellyfin -%{__mkdir} -p %{buildroot}%{_var}/cache/jellyfin - -%{__install} -D -m 0644 %{SOURCE11} %{buildroot}%{_unitdir}/%{name}.service -%{__install} -D -m 0644 %{SOURCE12} %{buildroot}%{_sysconfdir}/sysconfig/%{name} -%{__install} -D -m 0600 %{SOURCE13} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers -%{__install} -D -m 0755 %{SOURCE14} %{buildroot}%{_libexecdir}/%{name}/restart.sh -%{__install} -D -m 0644 %{SOURCE16} %{buildroot}%{_prefix}/lib/firewalld/services/%{name}.xml - -%files -%{_libdir}/%{name}/jellyfin-web/* -%attr(755,root,root) %{_bindir}/%{name} -%{_libdir}/%{name}/*.json -%{_libdir}/%{name}/*.dll -%{_libdir}/%{name}/*.so -%{_libdir}/%{name}/*.a -%{_libdir}/%{name}/createdump -# Needs 755 else only root can run it since binary build by dotnet is 722 -%attr(755,root,root) %{_libdir}/%{name}/jellyfin -%{_libdir}/%{name}/SOS_README.md -%{_unitdir}/%{name}.service -%{_libexecdir}/%{name}/restart.sh -%{_prefix}/lib/firewalld/services/%{name}.xml -%attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} -%config %{_sysconfdir}/sysconfig/%{name} -%config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers -%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf -%config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/%{name}/logging.json -%attr(750,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin -%attr(-,jellyfin,jellyfin) %dir %{_var}/log/jellyfin -%attr(750,jellyfin,jellyfin) %dir %{_var}/cache/jellyfin -%if 0%{?fedora} -%license LICENSE -%else -%{_datadir}/licenses/%{name}/LICENSE -%endif - -%pre -getent group jellyfin >/dev/null || groupadd -r jellyfin -getent passwd jellyfin >/dev/null || \ - useradd -r -g jellyfin -d %{_sharedstatedir}/jellyfin -s /sbin/nologin \ - -c "Jellyfin default user" jellyfin -exit 0 - -%post -# Move existing configuration cache and logs to their new locations and symlink them. -if [ $1 -gt 1 ] ; then - service_state=$(systemctl is-active jellyfin.service) - if [ "${service_state}" = "active" ]; then - systemctl stop jellyfin.service - fi - if [ ! -L %{_sharedstatedir}/%{name}/config ]; then - mv %{_sharedstatedir}/%{name}/config/* %{_sysconfdir}/%{name}/ - rmdir %{_sharedstatedir}/%{name}/config - ln -sf %{_sysconfdir}/%{name} %{_sharedstatedir}/%{name}/config - fi - if [ ! -L %{_sharedstatedir}/%{name}/logs ]; then - mv %{_sharedstatedir}/%{name}/logs/* %{_var}/log/jellyfin - rmdir %{_sharedstatedir}/%{name}/logs - ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/%{name}/logs - fi - if [ ! -L %{_sharedstatedir}/%{name}/cache ]; then - mv %{_sharedstatedir}/%{name}/cache/* %{_var}/cache/jellyfin - rmdir %{_sharedstatedir}/%{name}/cache - ln -sf %{_var}/cache/jellyfin %{_sharedstatedir}/%{name}/cache - fi - if [ "${service_state}" = "active" ]; then - systemctl start jellyfin.service - fi -fi -%systemd_post jellyfin.service - -%preun -%systemd_preun jellyfin.service - -%postun -%systemd_postun_with_restart jellyfin.service - -%changelog -* Fri Oct 11 2019 Jellyfin Packaging Team -- New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 -* Sat Aug 31 2019 Jellyfin Packaging Team -- New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 -* Wed Jul 24 2019 Jellyfin Packaging Team -- New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 -* Sat Jul 06 2019 Jellyfin Packaging Team -- New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 -* Sun Jun 09 2019 Jellyfin Packaging Team -- New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 -* Thu Jun 06 2019 Jellyfin Packaging Team -- New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 -* Fri May 17 2019 Jellyfin Packaging Team -- New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 -* Tue Apr 30 2019 Jellyfin Packaging Team -- New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 -* Sat Apr 20 2019 Jellyfin Packaging Team -- New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 -* Fri Apr 19 2019 Jellyfin Packaging Team -- New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers b/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers deleted file mode 100644 index dd245af4b8..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers +++ /dev/null @@ -1,19 +0,0 @@ -# Allow jellyfin group to start, stop and restart itself -Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin -Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin -Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin - - -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD - -Defaults!RESTARTSERVER_SYSTEMD !requiretty -Defaults!STARTSERVER_SYSTEMD !requiretty -Defaults!STOPSERVER_SYSTEMD !requiretty - -# Allow the server to mount iso images -jellyfin ALL=(ALL) NOPASSWD: /bin/mount -jellyfin ALL=(ALL) NOPASSWD: /bin/umount - -Defaults:jellyfin !requiretty diff --git a/deployment/old/fedora-package-x64/pkg-src/restart.sh b/deployment/old/fedora-package-x64/pkg-src/restart.sh deleted file mode 100755 index 9b64b6d728..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/restart.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# restart.sh - Jellyfin server restart script -# Part of the Jellyfin project (https://github.com/jellyfin) -# -# This script restarts the Jellyfin daemon on Linux when using -# the Restart button on the admin dashboard. It supports the -# systemctl, service, and traditional /etc/init.d (sysv) restart -# methods, chosen automatically by which one is found first (in -# that order). -# -# This script is used by the Debian/Ubuntu/Fedora/CentOS packages. - -get_service_command() { - for command in systemctl service; do - if which $command &>/dev/null; then - echo $command && return - fi - done - echo "sysv" -} - -cmd="$( get_service_command )" -echo "Detected service control platform '$cmd'; using it to restart Jellyfin..." -case $cmd in - 'systemctl') - echo "sleep 2; /usr/bin/sudo $( which systemctl ) restart jellyfin" | at now - ;; - 'service') - echo "sleep 2; /usr/bin/sudo $( which service ) jellyfin restart" | at now - ;; - 'sysv') - echo "sleep 2; /usr/bin/sudo /etc/init.d/jellyfin restart" | at now - ;; -esac -exit 0 diff --git a/deployment/old/linux-x64/Dockerfile b/deployment/old/linux-x64/Dockerfile deleted file mode 100644 index c47057546d..0000000000 --- a/deployment/old/linux-x64/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/linux-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/linux-x64/clean.sh b/deployment/old/linux-x64/clean.sh deleted file mode 100755 index c07501a7bb..0000000000 --- a/deployment/old/linux-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/linux-x64/dependencies.txt b/deployment/old/linux-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/linux-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/linux-x64/docker-build.sh b/deployment/old/linux-x64/docker-build.sh deleted file mode 100755 index e33328a36a..0000000000 --- a/deployment/old/linux-x64/docker-build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Builds the TAR archive inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build archives -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" -tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/linux-x64/package.sh b/deployment/old/linux-x64/package.sh deleted file mode 100755 index dfe8a9aa4a..0000000000 --- a/deployment/old/linux-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/macos/Dockerfile b/deployment/old/macos/Dockerfile deleted file mode 100644 index b522df8848..0000000000 --- a/deployment/old/macos/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/macos -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/macos/clean.sh b/deployment/old/macos/clean.sh deleted file mode 100755 index c07501a7bb..0000000000 --- a/deployment/old/macos/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/macos/dependencies.txt b/deployment/old/macos/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/macos/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/macos/docker-build.sh b/deployment/old/macos/docker-build.sh deleted file mode 100755 index f9417388d7..0000000000 --- a/deployment/old/macos/docker-build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Builds the TAR archive inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build archives -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" -tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/macos/package.sh b/deployment/old/macos/package.sh deleted file mode 100755 index 464c0d382f..0000000000 --- a/deployment/old/macos/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-macos-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/portable/Dockerfile b/deployment/old/portable/Dockerfile deleted file mode 100644 index 965eb82b86..0000000000 --- a/deployment/old/portable/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/portable -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/portable/clean.sh b/deployment/old/portable/clean.sh deleted file mode 100755 index c07501a7bb..0000000000 --- a/deployment/old/portable/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/portable/dependencies.txt b/deployment/old/portable/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/portable/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/portable/docker-build.sh b/deployment/old/portable/docker-build.sh deleted file mode 100755 index 094190bbf6..0000000000 --- a/deployment/old/portable/docker-build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Builds the TAR archive inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build archives -dotnet publish Jellyfin.Server --configuration Release --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" -tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/portable/package.sh b/deployment/old/portable/package.sh deleted file mode 100755 index 0ceb54dda1..0000000000 --- a/deployment/old/portable/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-portable-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 b/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 deleted file mode 100644 index b11994a18a..0000000000 --- a/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 +++ /dev/null @@ -1,59 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Prepare the cross-toolchain -RUN rm /etc/apt/sources.list \ - && export CODENAME="$( lsb_release -c -s )" \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && dpkg --add-architecture arm64 \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="arm64" cross-gcc-gensource 6 \ - && cd cross-gcc-packages-amd64/cross-gcc-6-arm64 \ - && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ - && apt-get install -y gcc-6-source libstdc++6-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 liblttng-ust0:arm64 libstdc++6:arm64 libssl-dev:arm64 - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 b/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 deleted file mode 100644 index 8f004b2f1a..0000000000 --- a/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 +++ /dev/null @@ -1,40 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=arm64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev liblttng-ust0 libssl-dev - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/5a4c8f96-1c73-401c-a6de-8e100403188a/0ce6ab39747e2508366d498f9c0a0669/dotnet-sdk-3.1.100-linux-arm64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-arm64/clean.sh b/deployment/old/ubuntu-package-arm64/clean.sh deleted file mode 100755 index 82d427f9e5..0000000000 --- a/deployment/old/ubuntu-package-arm64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/ubuntu-package-arm64/dependencies.txt b/deployment/old/ubuntu-package-arm64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/ubuntu-package-arm64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/ubuntu-package-arm64/docker-build.sh b/deployment/old/ubuntu-package-arm64/docker-build.sh deleted file mode 100755 index 67ab6bd74b..0000000000 --- a/deployment/old/ubuntu-package-arm64/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarm64 - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-arm64/package.sh b/deployment/old/ubuntu-package-arm64/package.sh deleted file mode 100755 index d1140a7274..0000000000 --- a/deployment/old/ubuntu-package-arm64/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu_arm64-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.arm64" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-arm64/pkg-src b/deployment/old/ubuntu-package-arm64/pkg-src deleted file mode 120000 index 4c695fea17..0000000000 --- a/deployment/old/ubuntu-package-arm64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 b/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 deleted file mode 100644 index e475b14389..0000000000 --- a/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 +++ /dev/null @@ -1,59 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Prepare the cross-toolchain -RUN rm /etc/apt/sources.list \ - && export CODENAME="$( lsb_release -c -s )" \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && dpkg --add-architecture armhf \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="armhf" cross-gcc-gensource 6 \ - && cd cross-gcc-packages-amd64/cross-gcc-6-armhf \ - && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ - && apt-get install -y gcc-6-source libstdc++6-armhf-cross binutils-arm-linux-gnueabihf bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf liblttng-ust0:armhf libstdc++6:armhf libssl-dev:armhf - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-armhf/Dockerfile.armhf b/deployment/old/ubuntu-package-armhf/Dockerfile.armhf deleted file mode 100644 index 0e71fa6938..0000000000 --- a/deployment/old/ubuntu-package-armhf/Dockerfile.armhf +++ /dev/null @@ -1,40 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=armhf - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev liblttng-ust0 libssl-dev - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/67766a96-eb8c-4cd2-bca4-ea63d2cc115c/7bf13840aa2ed88793b7315d5e0d74e6/dotnet-sdk-3.1.100-linux-arm.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-armhf/clean.sh b/deployment/old/ubuntu-package-armhf/clean.sh deleted file mode 100755 index 82d427f9e5..0000000000 --- a/deployment/old/ubuntu-package-armhf/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/ubuntu-package-armhf/dependencies.txt b/deployment/old/ubuntu-package-armhf/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/ubuntu-package-armhf/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/ubuntu-package-armhf/docker-build.sh b/deployment/old/ubuntu-package-armhf/docker-build.sh deleted file mode 100755 index 1bd7fb2911..0000000000 --- a/deployment/old/ubuntu-package-armhf/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarmhf - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-armhf/package.sh b/deployment/old/ubuntu-package-armhf/package.sh deleted file mode 100755 index 2ceb3e8165..0000000000 --- a/deployment/old/ubuntu-package-armhf/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu_armhf-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.armhf" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-armhf/pkg-src b/deployment/old/ubuntu-package-armhf/pkg-src deleted file mode 120000 index 4c695fea17..0000000000 --- a/deployment/old/ubuntu-package-armhf/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/ubuntu-package-x64/Dockerfile b/deployment/old/ubuntu-package-x64/Dockerfile deleted file mode 100644 index e2dda6392c..0000000000 --- a/deployment/old/ubuntu-package-x64/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Ubuntu build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 \ - && ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ - && mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-x64/clean.sh b/deployment/old/ubuntu-package-x64/clean.sh deleted file mode 100755 index 82d427f9e5..0000000000 --- a/deployment/old/ubuntu-package-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/ubuntu-package-x64/dependencies.txt b/deployment/old/ubuntu-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/ubuntu-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/ubuntu-package-x64/docker-build.sh b/deployment/old/ubuntu-package-x64/docker-build.sh deleted file mode 100755 index 962a522ebc..0000000000 --- a/deployment/old/ubuntu-package-x64/docker-build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -dpkg-buildpackage -us -uc - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-x64/package.sh b/deployment/old/ubuntu-package-x64/package.sh deleted file mode 100755 index 08c003778b..0000000000 --- a/deployment/old/ubuntu-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-x64/pkg-src b/deployment/old/ubuntu-package-x64/pkg-src deleted file mode 120000 index 0bb6d55249..0000000000 --- a/deployment/old/ubuntu-package-x64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/unraid/docker-templates/README.md b/deployment/old/unraid/docker-templates/README.md deleted file mode 100644 index 2c268e8b3e..0000000000 --- a/deployment/old/unraid/docker-templates/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# docker-templates - -### Installation: - -Open unRaid GUI (at least unRaid 6.5) - -Click on the Docker tab - -Add the following line under "Template Repositories" - -https://github.com/jellyfin/jellyfin/blob/master/deployment/unraid/docker-templates - -Click save than click on Add Container and select jellyfin. - -Adjust to your paths to your liking and off you go! diff --git a/deployment/old/unraid/docker-templates/jellyfin.xml b/deployment/old/unraid/docker-templates/jellyfin.xml deleted file mode 100644 index 57b4cc5ae1..0000000000 --- a/deployment/old/unraid/docker-templates/jellyfin.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - https://raw.githubusercontent.com/jellyfin/jellyfin/deployment/unraid/docker-templates/jellyfin.xml - False - MediaApp:Video MediaApp:Music MediaApp:Photos MediaServer:Video MediaServer:Music MediaServer:Photos - Jellyfin - - Jellyfin is The Free Software Media Browser Converted By Community Applications Always verify this template (and values) against the dockerhub support page for the container!![br][br] - You can add as many mount points as needed for recordings, movies ,etc. [br][br] - [b][span style='color: #E80000;']Directions:[/span][/b][br] - [b]/config[/b] : This is where Jellyfin will store it's databases and configuration.[br][br] - [b]Port[/b] : This is the default port for Jellyfin. (Will add ssl port later)[br][br] - [b]Media[/b] : This is the mounting point of your media. When you access it in Jellyfin it will be /media or whatever you chose for a mount point[br][br] - [b]Cache[/b] : This is where Jellyfin will store and manage cached files like images to serve to clients. This is not where all images are stored.[br][br] - [b]Tip:[/b] You can add more volume mappings if you wish Jellyfin has access to it. - - - Jellyfin Server is a home media server built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono and will remain completely free! - - https://www.reddit.com/r/jellyfin/ - https://hub.docker.com/r/jellyfin/jellyfin/ - https://github.com/jellyfin/jellyfin/> - jellyfin/jellyfin - https://jellyfin.media/ - true - false - - host - - - 8096 - 8096 - tcp - - - - - - /mnt/user/appdata/Jellyfin - /config - rw - - - /mnt/user - /media - rw - - - /mnt/user/appdata/Jellyfin/cache/ - /cache - rw - - - http://[IP]:[PORT:8096]/ - https://raw.githubusercontent.com/binhex/docker-templates/master/binhex/images/jellyfin-icon.png - - diff --git a/deployment/old/win-x64/Dockerfile b/deployment/old/win-x64/Dockerfile deleted file mode 100644 index 8a33749541..0000000000 --- a/deployment/old/win-x64/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/win-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/win-x64/clean.sh b/deployment/old/win-x64/clean.sh deleted file mode 100755 index 6c183f3371..0000000000 --- a/deployment/old/win-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x64-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/win-x64/dependencies.txt b/deployment/old/win-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/win-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/win-x64/docker-build.sh b/deployment/old/win-x64/docker-build.sh deleted file mode 100755 index 79e5fb0bcd..0000000000 --- a/deployment/old/win-x64/docker-build.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Builds the ZIP archive inside the Docker container - -set -o errexit -set -o xtrace - -# Version variables -NSSM_VERSION="nssm-2.24-101-g897c7ad" -NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" -FFMPEG_VERSION="ffmpeg-4.2.1-win64-static" -FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win64/static/${FFMPEG_VERSION}.zip" - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build binary -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" - -# Prepare addins -addin_build_dir="$( mktemp -d )" -wget ${NSSM_URL} -O ${addin_build_dir}/nssm.zip -wget ${FFMPEG_URL} -O ${addin_build_dir}/ffmpeg.zip -unzip ${addin_build_dir}/nssm.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${NSSM_VERSION}/win64/nssm.exe /dist/jellyfin_${version}/nssm.exe -unzip ${addin_build_dir}/ffmpeg.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffmpeg.exe /dist/jellyfin_${version}/ffmpeg.exe -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffprobe.exe /dist/jellyfin_${version}/ffprobe.exe -rm -rf ${addin_build_dir} - -# Prepare scripts -cp ${SOURCE_DIR}/deployment/windows/legacy/install-jellyfin.ps1 /dist/jellyfin_${version}/install-jellyfin.ps1 -cp ${SOURCE_DIR}/deployment/windows/legacy/install.bat /dist/jellyfin_${version}/install.bat - -# Create zip package -pushd /dist -zip -r /jellyfin_${version}.portable.zip jellyfin_${version} -popd -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.zip ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/win-x64/package.sh b/deployment/old/win-x64/package.sh deleted file mode 100755 index a8ab190fa5..0000000000 --- a/deployment/old/win-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x64-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/win-x86/Dockerfile b/deployment/old/win-x86/Dockerfile deleted file mode 100644 index f8dc5be83d..0000000000 --- a/deployment/old/win-x86/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/win-x86 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/win-x86/clean.sh b/deployment/old/win-x86/clean.sh deleted file mode 100755 index 8b78c5e4b6..0000000000 --- a/deployment/old/win-x86/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x86-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/win-x86/dependencies.txt b/deployment/old/win-x86/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/win-x86/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/win-x86/docker-build.sh b/deployment/old/win-x86/docker-build.sh deleted file mode 100755 index 977dcf78fa..0000000000 --- a/deployment/old/win-x86/docker-build.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Builds the ZIP archive inside the Docker container - -set -o errexit -set -o xtrace - -# Version variables -NSSM_VERSION="nssm-2.24-101-g897c7ad" -NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" -FFMPEG_VERSION="ffmpeg-4.2.1-win32-static" -FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win32/static/${FFMPEG_VERSION}.zip" - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build binary -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x86 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" - -# Prepare addins -addin_build_dir="$( mktemp -d )" -wget ${NSSM_URL} -O ${addin_build_dir}/nssm.zip -wget ${FFMPEG_URL} -O ${addin_build_dir}/ffmpeg.zip -unzip ${addin_build_dir}/nssm.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${NSSM_VERSION}/win64/nssm.exe /dist/jellyfin_${version}/nssm.exe -unzip ${addin_build_dir}/ffmpeg.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffmpeg.exe /dist/jellyfin_${version}/ffmpeg.exe -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffprobe.exe /dist/jellyfin_${version}/ffprobe.exe -rm -rf ${addin_build_dir} - -# Prepare scripts -cp ${SOURCE_DIR}/deployment/windows/legacy/install-jellyfin.ps1 /dist/jellyfin_${version}/install-jellyfin.ps1 -cp ${SOURCE_DIR}/deployment/windows/legacy/install.bat /dist/jellyfin_${version}/install.bat - -# Create zip package -pushd /dist -zip -r /jellyfin_${version}.portable.zip jellyfin_${version} -popd -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.zip ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/win-x86/package.sh b/deployment/old/win-x86/package.sh deleted file mode 100755 index 65e7e2928c..0000000000 --- a/deployment/old/win-x86/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x86-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" From cd616746b9ec4c1e07b84e207104bad01c614dae Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Tue, 24 Mar 2020 11:17:01 -0400 Subject: [PATCH 051/517] Use more specific mv source glob --- deployment/build.debian.amd64 | 2 +- deployment/build.debian.arm64 | 2 +- deployment/build.debian.armhf | 2 +- deployment/build.ubuntu.amd64 | 2 +- deployment/build.ubuntu.arm64 | 2 +- deployment/build.ubuntu.armhf | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deployment/build.debian.amd64 b/deployment/build.debian.amd64 index beaf02bee2..f44c6a7d1d 100755 --- a/deployment/build.debian.amd64 +++ b/deployment/build.debian.amd64 @@ -18,7 +18,7 @@ fi dpkg-buildpackage -us -uc --pre-clean --post-clean mkdir -p ${ARTIFACT_DIR}/ -mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ +mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then cp -a /tmp/control.orig debian/control diff --git a/deployment/build.debian.arm64 b/deployment/build.debian.arm64 index 6394dddb02..0127671f3d 100755 --- a/deployment/build.debian.arm64 +++ b/deployment/build.debian.arm64 @@ -19,7 +19,7 @@ export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} dpkg-buildpackage -us -uc -a arm64 --pre-clean --post-clean mkdir -p ${ARTIFACT_DIR}/ -mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ +mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then cp -a /tmp/control.orig debian/control diff --git a/deployment/build.debian.armhf b/deployment/build.debian.armhf index d12660760f..02e3db4fca 100755 --- a/deployment/build.debian.armhf +++ b/deployment/build.debian.armhf @@ -19,7 +19,7 @@ export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} dpkg-buildpackage -us -uc -a armhf --pre-clean --post-clean mkdir -p ${ARTIFACT_DIR}/ -mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ +mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then cp -a /tmp/control.orig debian/control diff --git a/deployment/build.ubuntu.amd64 b/deployment/build.ubuntu.amd64 index 1b90f68f46..107ddbe02d 100755 --- a/deployment/build.ubuntu.amd64 +++ b/deployment/build.ubuntu.amd64 @@ -18,7 +18,7 @@ fi dpkg-buildpackage -us -uc --pre-clean --post-clean mkdir -p ${ARTIFACT_DIR}/ -mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ +mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then cp -a /tmp/control.orig debian/control diff --git a/deployment/build.ubuntu.arm64 b/deployment/build.ubuntu.arm64 index c0a31d764f..b13868f44b 100755 --- a/deployment/build.ubuntu.arm64 +++ b/deployment/build.ubuntu.arm64 @@ -19,7 +19,7 @@ export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} dpkg-buildpackage -us -uc -a arm64 --pre-clean --post-clean mkdir -p ${ARTIFACT_DIR}/ -mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ +mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then cp -a /tmp/control.orig debian/control diff --git a/deployment/build.ubuntu.armhf b/deployment/build.ubuntu.armhf index e2129357dd..0b4dd308a2 100755 --- a/deployment/build.ubuntu.armhf +++ b/deployment/build.ubuntu.armhf @@ -19,7 +19,7 @@ export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} dpkg-buildpackage -us -uc -a armhf --pre-clean --post-clean mkdir -p ${ARTIFACT_DIR}/ -mv ../jellyfin[-_]* ${ARTIFACT_DIR}/ +mv ../jellyfin*.{deb,dsc,tar.gz,buildinfo,changes} ${ARTIFACT_DIR}/ if [[ ${IS_DOCKER} == YES ]]; then cp -a /tmp/control.orig debian/control From 8094687b9c589038ce87879c51785cd63c8ef8ac Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 30 Mar 2020 02:40:06 -0400 Subject: [PATCH 052/517] Add Debian/Ubuntu metapackage equivs file --- debian/metapackage/jellyfin | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 debian/metapackage/jellyfin diff --git a/debian/metapackage/jellyfin b/debian/metapackage/jellyfin new file mode 100644 index 0000000000..9a41eafaed --- /dev/null +++ b/debian/metapackage/jellyfin @@ -0,0 +1,13 @@ +Source: jellyfin +Section: misc +Priority: optional +Homepage: https://jellyfin.org +Standards-Version: 3.9.2 + +Package: jellyfin +Version: 10.6.0 +Maintainer: Jellyfin Packaging Team +Depends: jellyfin-server, jellyfin-web +Description: Provides the Jellyfin Free Software Media System + Provides the full Jellyfin experience, including both the server and web interface. + From 49da8766d8aac23ab6f6c64a4fee1885b04918f3 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 30 Mar 2020 02:43:13 -0400 Subject: [PATCH 053/517] Update bump_version script 1. Remove some cruft 2. Update the metapackage as well 3. Changelogs are automated, don't bother EDITOR-ing them --- bump_version | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/bump_version b/bump_version index 106dd7a78e..c868c541e6 100755 --- a/bump_version +++ b/bump_version @@ -10,10 +10,6 @@ usage() { echo -e "" echo -e "Usage:" echo -e " $ bump_version " - echo -e "" - echo -e "The web_branch defaults to the same branch name as the current main branch." - echo -e "This helps facilitate releases where both branches would be called release-X.Y.Z" - echo -e "and would already be created before running this script." } if [[ -z $1 ]]; then @@ -54,37 +50,28 @@ else new_version_deb="${new_version}-1" fi -# Set the Dockerfile web version to the specified new_version -old_version="$( - grep "JELLYFIN_WEB_VERSION=" Dockerfile \ - | sed -E 's/ARG JELLYFIN_WEB_VERSION=v([0-9\.]+[-a-z0-9]*)/\1/' -)" -echo $old_version - -old_version_sed="$( sed 's/\./\\./g' <<<"${old_version}" )" # Escape the '.' chars -sed -i "s/${old_version_sed}/${new_version}/g" Dockerfile* +# Update the metapackage equivs file +debian_equivs_file="debian/metapackage/jellyfin" +sed -i "s/${old_version_sed}/${new_version}/g" ${debian_equivs_file} # Write out a temporary Debian changelog with our new stuff appended and some templated formatting -debian_changelog_file="deployment/debian-package-x64/pkg-src/changelog" +debian_changelog_file="debian/changelog" debian_changelog_temp="$( mktemp )" # Create new temp file with our changelog -echo -e "### DEBIAN PACKAGE CHANGELOG: Verify this file looks correct or edit accordingly, then delete this line, write, and exit. -jellyfin (${new_version_deb}) unstable; urgency=medium +echo -e "jellyfin (${new_version_deb}) unstable; urgency=medium * New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v${new_version} -- Jellyfin Packaging Team $( date --rfc-2822 ) " >> ${debian_changelog_temp} cat ${debian_changelog_file} >> ${debian_changelog_temp} -# Edit the file to verify -$EDITOR ${debian_changelog_temp} # Move into place mv ${debian_changelog_temp} ${debian_changelog_file} # Clean up rm -f ${debian_changelog_temp} # Write out a temporary Yum changelog with our new stuff prepended and some templated formatting -fedora_spec_file="deployment/fedora-package-x64/pkg-src/jellyfin.spec" +fedora_spec_file="fedora/jellyfin.spec" fedora_changelog_temp="$( mktemp )" fedora_spec_temp_dir="$( mktemp -d )" fedora_spec_temp="${fedora_spec_temp_dir}/jellyfin.spec.tmp" @@ -98,13 +85,10 @@ sed -i "s/${old_version_sed}/${new_version_sed}/g" xx00 # Remove the header from xx01 sed -i '/^%changelog/d' xx01 # Create new temp file with our changelog -echo -e "### YUM SPEC CHANGELOG: Verify this file looks correct or edit accordingly, then delete this line, write, and exit. -%changelog +echo -e "%changelog * $( LANG=C date '+%a %b %d %Y' ) Jellyfin Packaging Team - New upstream version ${new_version}; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v${new_version}" >> ${fedora_changelog_temp} cat xx01 >> ${fedora_changelog_temp} -# Edit the file to verify -$EDITOR ${fedora_changelog_temp} # Reassembble cat xx00 ${fedora_changelog_temp} > ${fedora_spec_temp} popd @@ -114,5 +98,5 @@ mv ${fedora_spec_temp} ${fedora_spec_file} rm -rf ${fedora_changelog_temp} ${fedora_spec_temp_dir} # Stage the changed files for commit -git add ${shared_version_file} ${build_file} ${debian_changelog_file} ${fedora_spec_file} Dockerfile* +git add ${shared_version_file} ${build_file} ${debian_equivs_file} ${debian_changelog_file} ${fedora_spec_file} git status From ca71ac72abf5d5ff31d50553283a43de298e0c73 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Thu, 2 Apr 2020 17:45:04 -0400 Subject: [PATCH 054/517] Replace EnableHttps and SupportsHttps with ListenWithHttps and CanConnectWithHttps --- Emby.Server.Implementations/ApplicationHost.cs | 15 ++++++++++----- .../EntryPoints/ExternalPortForwarding.cs | 2 +- .../HttpServer/HttpListenerHost.cs | 2 +- Jellyfin.Server/Program.cs | 4 ++-- MediaBrowser.Controller/IServerApplicationHost.cs | 5 ++--- MediaBrowser.Model/System/SystemInfo.cs | 4 ++-- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index c959cc974a..8158b45592 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1408,7 +1408,7 @@ namespace Emby.Server.Implementations InternalMetadataPath = ApplicationPaths.InternalMetadataPath, CachePath = ApplicationPaths.CachePath, HttpServerPortNumber = HttpPort, - SupportsHttps = SupportsHttps, + SupportsHttps = CanConnectWithHttps, HttpsPortNumber = HttpsPort, OperatingSystem = OperatingSystem.Id.ToString(), OperatingSystemDisplayName = OperatingSystem.Name, @@ -1446,9 +1446,14 @@ namespace Emby.Server.Implementations }; } - public bool EnableHttps => SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps; + /// + public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.Configuration.EnableHttps; - public bool SupportsHttps => Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy; + /// + /// Gets a value indicating whether a client can connect to the server over HTTPS, either directly or via a + /// reverse proxy. + /// + public bool CanConnectWithHttps => ListenWithHttps || ServerConfigurationManager.Configuration.IsBehindProxy; public async Task GetLocalApiUrl(CancellationToken cancellationToken) { @@ -1509,10 +1514,10 @@ namespace Emby.Server.Implementations public string GetLocalApiUrl(ReadOnlySpan host) { var url = new StringBuilder(64); - url.Append(EnableHttps ? "https://" : "http://") + url.Append(ListenWithHttps ? "https://" : "http://") .Append(host) .Append(':') - .Append(EnableHttps ? HttpsPort : HttpPort); + .Append(ListenWithHttps ? HttpsPort : HttpPort); string baseUrl = ServerConfigurationManager.Configuration.BaseUrl; if (baseUrl.Length != 0) diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index e290c62e16..2023c470a8 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.EntryPoints .Append(config.PublicPort).Append(Separator) .Append(_appHost.HttpPort).Append(Separator) .Append(_appHost.HttpsPort).Append(Separator) - .Append(_appHost.EnableHttps).Append(Separator) + .Append(_appHost.ListenWithHttps).Append(Separator) .Append(config.EnableRemoteAccess).Append(Separator) .ToString(); } diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 7a812f3201..e3f8ec0146 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -422,7 +422,7 @@ namespace Emby.Server.Implementations.HttpServer private bool ValidateSsl(string remoteIp, string urlString) { - if (_config.Configuration.RequireHttps && _appHost.EnableHttps && !_config.Configuration.IsBehindProxy) + if (_config.Configuration.RequireHttps && _appHost.ListenWithHttps) { if (urlString.IndexOf("https://", StringComparison.OrdinalIgnoreCase) == -1) { diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 4abdd59aaf..ddd1054ad0 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -274,7 +274,7 @@ namespace Jellyfin.Server _logger.LogInformation("Kestrel listening on {IpAddress}", address); options.Listen(address, appHost.HttpPort); - if (appHost.EnableHttps && appHost.Certificate != null) + if (appHost.ListenWithHttps) { options.Listen(address, appHost.HttpsPort, listenOptions => { @@ -289,7 +289,7 @@ namespace Jellyfin.Server _logger.LogInformation("Kestrel listening on all interfaces"); options.ListenAnyIP(appHost.HttpPort); - if (appHost.EnableHttps && appHost.Certificate != null) + if (appHost.ListenWithHttps) { options.ListenAnyIP(appHost.HttpsPort, listenOptions => { diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 608ffc61c2..d999f76dbf 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -39,10 +39,9 @@ namespace MediaBrowser.Controller int HttpsPort { get; } /// - /// Gets a value indicating whether [supports HTTPS]. + /// Gets a value indicating whether the server should listen on an HTTPS port. /// - /// true if [supports HTTPS]; otherwise, false. - bool EnableHttps { get; } + bool ListenWithHttps { get; } /// /// Gets a value indicating whether this instance has update available. diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index cfa7684c91..83c60563e7 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -124,9 +124,9 @@ namespace MediaBrowser.Model.System public int HttpServerPortNumber { get; set; } /// - /// Gets or sets a value indicating whether [enable HTTPS]. + /// Gets or sets a value indicating whether a client can connect to the server over HTTPS, either directly or + /// via a reverse proxy. /// - /// true if [enable HTTPS]; otherwise, false. public bool SupportsHttps { get; set; } /// From 387fa474aa8ee8e237648ab0ea3130b8b35cf92f Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Thu, 2 Apr 2020 17:45:33 -0400 Subject: [PATCH 055/517] Document HTTPS configuration options --- .../HttpServer/HttpListenerHost.cs | 4 +++ .../Configuration/ServerConfiguration.cs | 35 ++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index e3f8ec0146..dc542af784 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -420,6 +420,10 @@ namespace Emby.Server.Implementations.HttpServer return true; } + /// + /// Validate a connection from a remote IP address to a URL to see if a redirection to HTTPS is required. + /// + /// True if the request is valid, or false if the request is not valid and an HTTPS redirect is required. private bool ValidateSsl(string remoteIp, string urlString) { if (_config.Configuration.RequireHttps && _appHost.ListenWithHttps) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 3107ec2426..b14b347ccc 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -45,17 +45,24 @@ namespace MediaBrowser.Model.Configuration public int HttpsPortNumber { get; set; } /// - /// Gets or sets a value indicating whether [use HTTPS]. + /// Gets or sets a value indicating whether to use HTTPS. /// - /// true if [use HTTPS]; otherwise, false. + /// + /// In order for HTTPS to be used, in addition to setting this to true, valid values must also be + /// provided for and . + /// public bool EnableHttps { get; set; } + public bool EnableNormalizedItemByNameIds { get; set; } /// - /// Gets or sets the value pointing to the file system where the ssl certificate is located.. + /// Gets or sets the filesystem path of an X.509 certificate to use for SSL. /// - /// The value pointing to the file system where the ssl certificate is located.. public string CertificatePath { get; set; } + + /// + /// Gets or sets the password required to access the X.509 certificate data in the file specified by . + /// public string CertificatePassword { get; set; } /// @@ -65,8 +72,11 @@ namespace MediaBrowser.Model.Configuration public bool IsPortAuthorized { get; set; } public bool AutoRunWebApp { get; set; } + public bool EnableRemoteAccess { get; set; } + public bool CameraUploadUpgraded { get; set; } + public bool CollectionsUpgraded { get; set; } /// @@ -82,6 +92,7 @@ namespace MediaBrowser.Model.Configuration /// /// The metadata path. public string MetadataPath { get; set; } + public string MetadataNetworkPath { get; set; } /// @@ -204,15 +215,31 @@ namespace MediaBrowser.Model.Configuration public int RemoteClientBitrateLimit { get; set; } public bool EnableFolderView { get; set; } + public bool EnableGroupingIntoCollections { get; set; } + public bool DisplaySpecialsWithinSeasons { get; set; } + public string[] LocalNetworkSubnets { get; set; } + public string[] LocalNetworkAddresses { get; set; } + public string[] CodecsUsed { get; set; } + public bool IgnoreVirtualInterfaces { get; set; } + public bool EnableExternalContentInSuggestions { get; set; } + + /// + /// Gets or sets a value indicating whether the server should force connections over HTTPS. + /// public bool RequireHttps { get; set; } + + /// + /// Gets or sets a value indicating whether the server is behind a reverse proxy. + /// public bool IsBehindProxy { get; set; } + public bool EnableNewOmdbSupport { get; set; } public string[] RemoteIPFilter { get; set; } From e9e12b8eb97947f3387dcfac00fe9aa5e845d9e9 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:26:24 -0400 Subject: [PATCH 056/517] Register ISubtitleEncoder correctly --- Emby.Server.Implementations/ApplicationHost.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index c959cc974a..27dd0ec1ad 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -845,16 +845,7 @@ namespace Emby.Server.Implementations AuthService = new AuthService(LoggerFactory.CreateLogger(), authContext, ServerConfigurationManager, SessionManager, NetworkManager); serviceCollection.AddSingleton(AuthService); - SubtitleEncoder = new MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder( - LibraryManager, - LoggerFactory.CreateLogger(), - ApplicationPaths, - FileSystemManager, - MediaEncoder, - HttpClient, - MediaSourceManager, - ProcessFactory); - serviceCollection.AddSingleton(SubtitleEncoder); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager)); serviceCollection.AddSingleton(); @@ -880,6 +871,7 @@ namespace Emby.Server.Implementations public void InitializeServices() { HttpServer = Resolve(); + SubtitleEncoder = Resolve(); } public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths) From 92b0d40ad40cdf0e35ecd1a9e1680fd5b8e6ef2f Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:33:25 -0400 Subject: [PATCH 057/517] Move service initializations into correct method --- .../ApplicationHost.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 27dd0ec1ad..f985320350 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -851,6 +851,16 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); serviceCollection.AddSingleton(typeof(IAttachmentExtractor), typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor)); + } + + /// + /// Create services registered with the service container that need to be initialized at application startup. + /// + public void InitializeServices() + { + HttpServer = Resolve(); + AuthService = Resolve(); + SubtitleEncoder = Resolve(); _displayPreferencesRepository.Initialize(); @@ -865,15 +875,6 @@ namespace Emby.Server.Implementations ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; } - /// - /// Create services registered with the service container that need to be initialized at application startup. - /// - public void InitializeServices() - { - HttpServer = Resolve(); - SubtitleEncoder = Resolve(); - } - public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths) { // Distinct these to prevent users from reporting problems that aren't actually problems From 314711147181ae26af4857b113b0e2acdcf10931 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:34:01 -0400 Subject: [PATCH 058/517] Register IAuthService correctly --- Emby.Server.Implementations/ApplicationHost.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f985320350..00700a3064 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -842,8 +842,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(authContext); serviceCollection.AddSingleton(new SessionContext(UserManager, authContext, SessionManager)); - AuthService = new AuthService(LoggerFactory.CreateLogger(), authContext, ServerConfigurationManager, SessionManager, NetworkManager); - serviceCollection.AddSingleton(AuthService); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); From 358deecf52370ef764b65d56f83a21d0eebcd91a Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:38:59 -0400 Subject: [PATCH 059/517] Register ISessionContext correctly --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 00700a3064..a90f14b1f5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -840,7 +840,7 @@ namespace Emby.Server.Implementations var authContext = new AuthorizationContext(AuthenticationRepository, UserManager); serviceCollection.AddSingleton(authContext); - serviceCollection.AddSingleton(new SessionContext(UserManager, authContext, SessionManager)); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); From 18c1823cead357ada7094675175b20b3399cafcb Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:40:33 -0400 Subject: [PATCH 060/517] Register IAuthorizationContext correctly --- Emby.Server.Implementations/ApplicationHost.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index a90f14b1f5..c177989116 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -838,8 +838,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(activityLogRepo); serviceCollection.AddSingleton(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); - var authContext = new AuthorizationContext(AuthenticationRepository, UserManager); - serviceCollection.AddSingleton(authContext); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); From 3dbbe54f6c94ae279aa74eff3bfa380a665e02a9 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:42:21 -0400 Subject: [PATCH 061/517] Register IResourceFileManager correctly --- Emby.Server.Implementations/ApplicationHost.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index c177989116..46fa4d4b4d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -845,7 +845,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager)); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(typeof(IAttachmentExtractor), typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor)); From 4ba07b114d78b042dce111e2345f87b375d8da6e Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:46:35 -0400 Subject: [PATCH 062/517] Register and initialize IActivityRepository correctly --- Emby.Server.Implementations/ApplicationHost.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 46fa4d4b4d..3209ab3b78 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -834,9 +834,8 @@ namespace Emby.Server.Implementations LibraryManager); serviceCollection.AddSingleton(EncodingManager); - var activityLogRepo = GetActivityLogRepository(); - serviceCollection.AddSingleton(activityLogRepo); - serviceCollection.AddSingleton(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); + serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -860,6 +859,7 @@ namespace Emby.Server.Implementations AuthService = Resolve(); SubtitleEncoder = Resolve(); + ((ActivityRepository)Resolve()).Initialize(); _displayPreferencesRepository.Initialize(); var userDataRepo = new SqliteUserDataRepository(LoggerFactory.CreateLogger(), ApplicationPaths); @@ -963,15 +963,6 @@ namespace Emby.Server.Implementations return repo; } - private IActivityRepository GetActivityLogRepository() - { - var repo = new ActivityRepository(LoggerFactory, ServerConfigurationManager.ApplicationPaths, FileSystemManager); - - repo.Initialize(); - - return repo; - } - /// /// Dirty hacks. /// From 7884c3813d682ca6ae8d7df4a6ba11f61e1d8ae0 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:51:56 -0400 Subject: [PATCH 063/517] Register IEncodingManager correctly; remove unnecessary properties in ApplicationHost --- .../ApplicationHost.cs | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 3209ab3b78..7d72b8e08b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -282,16 +282,12 @@ namespace Emby.Server.Implementations /// The media encoder. private IMediaEncoder MediaEncoder { get; set; } - private ISubtitleEncoder SubtitleEncoder { get; set; } - private ISessionManager SessionManager { get; set; } private ILiveTvManager LiveTvManager { get; set; } public LocalizationManager LocalizationManager { get; set; } - private IEncodingManager EncodingManager { get; set; } - private IChannelManager ChannelManager { get; set; } /// @@ -326,8 +322,6 @@ namespace Emby.Server.Implementations /// The installation manager. protected IInstallationManager InstallationManager { get; private set; } - protected IAuthService AuthService { get; private set; } - public IStartupOptions StartupOptions { get; } internal IImageEncoder ImageEncoder { get; private set; } @@ -740,7 +734,7 @@ namespace Emby.Server.Implementations FileSystemManager, ProcessFactory, LocalizationManager, - () => SubtitleEncoder, + ServiceProvider.GetRequiredService, startupConfig, StartupOptions.FFmpegPath); serviceCollection.AddSingleton(MediaEncoder); @@ -826,13 +820,7 @@ namespace Emby.Server.Implementations ChapterManager = new ChapterManager(ItemRepository); serviceCollection.AddSingleton(ChapterManager); - EncodingManager = new MediaEncoder.EncodingManager( - LoggerFactory.CreateLogger(), - FileSystemManager, - MediaEncoder, - ChapterManager, - LibraryManager); - serviceCollection.AddSingleton(EncodingManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -856,8 +844,6 @@ namespace Emby.Server.Implementations public void InitializeServices() { HttpServer = Resolve(); - AuthService = Resolve(); - SubtitleEncoder = Resolve(); ((ActivityRepository)Resolve()).Initialize(); _displayPreferencesRepository.Initialize(); @@ -989,7 +975,7 @@ namespace Emby.Server.Implementations CollectionFolder.XmlSerializer = XmlSerializer; CollectionFolder.JsonSerializer = JsonSerializer; CollectionFolder.ApplicationHost = this; - AuthenticatedAttribute.AuthService = AuthService; + AuthenticatedAttribute.AuthService = ServiceProvider.GetRequiredService(); } private async void PluginInstalled(object sender, GenericEventArgs args) From 78370911c20d83b4f7fc9ca1fb89e5fdd978f0ef Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 12:56:36 -0400 Subject: [PATCH 064/517] Register IDeviceDiscovery, IChapterManager, IAttachmentExtractor correctly --- Emby.Server.Implementations/ApplicationHost.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 7d72b8e08b..777c12eaed 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -302,8 +302,6 @@ namespace Emby.Server.Implementations private ISubtitleManager SubtitleManager { get; set; } - private IChapterManager ChapterManager { get; set; } - private IDeviceManager DeviceManager { get; set; } internal IUserViewManager UserViewManager { get; set; } @@ -815,10 +813,9 @@ namespace Emby.Server.Implementations ServerConfigurationManager); serviceCollection.AddSingleton(NotificationManager); - serviceCollection.AddSingleton(new DeviceDiscovery(ServerConfigurationManager)); + serviceCollection.AddSingleton(); - ChapterManager = new ChapterManager(ItemRepository); - serviceCollection.AddSingleton(ChapterManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -835,7 +832,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(typeof(IAttachmentExtractor), typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor)); + serviceCollection.AddSingleton(); } /// From f1d0fb1edb56e488bb1ef8f7b4ca2cd9b878f312 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 13:03:32 -0400 Subject: [PATCH 065/517] Register INotificationManager correctly; resolve services correctly --- Emby.Server.Implementations/ApplicationHost.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 777c12eaed..0fcfedd6bc 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -732,7 +732,7 @@ namespace Emby.Server.Implementations FileSystemManager, ProcessFactory, LocalizationManager, - ServiceProvider.GetRequiredService, + Resolve, startupConfig, StartupOptions.FFmpegPath); serviceCollection.AddSingleton(MediaEncoder); @@ -807,11 +807,7 @@ namespace Emby.Server.Implementations UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); serviceCollection.AddSingleton(UserViewManager); - NotificationManager = new NotificationManager( - LoggerFactory.CreateLogger(), - UserManager, - ServerConfigurationManager); - serviceCollection.AddSingleton(NotificationManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -840,6 +836,7 @@ namespace Emby.Server.Implementations /// public void InitializeServices() { + NotificationManager = Resolve(); HttpServer = Resolve(); ((ActivityRepository)Resolve()).Initialize(); @@ -972,7 +969,7 @@ namespace Emby.Server.Implementations CollectionFolder.XmlSerializer = XmlSerializer; CollectionFolder.JsonSerializer = JsonSerializer; CollectionFolder.ApplicationHost = this; - AuthenticatedAttribute.AuthService = ServiceProvider.GetRequiredService(); + AuthenticatedAttribute.AuthService = Resolve(); } private async void PluginInstalled(object sender, GenericEventArgs args) From 14563654113192fbf162c5238c79a0f908587c05 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 13:10:39 -0400 Subject: [PATCH 066/517] Register IUserViewManager correctly --- Emby.Server.Implementations/ApplicationHost.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 0fcfedd6bc..aa1e9ab9d4 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -304,8 +304,6 @@ namespace Emby.Server.Implementations private IDeviceManager DeviceManager { get; set; } - internal IUserViewManager UserViewManager { get; set; } - private IAuthenticationRepository AuthenticationRepository { get; set; } private ITVSeriesManager TVSeriesManager { get; set; } @@ -737,7 +735,7 @@ namespace Emby.Server.Implementations StartupOptions.FFmpegPath); serviceCollection.AddSingleton(MediaEncoder); - LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, () => UserViewManager, MediaEncoder); + LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, Resolve, MediaEncoder); serviceCollection.AddSingleton(LibraryManager); var musicManager = new MusicManager(LibraryManager); @@ -804,8 +802,7 @@ namespace Emby.Server.Implementations LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, LoggerFactory, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, FileSystemManager, () => ChannelManager); serviceCollection.AddSingleton(LiveTvManager); - UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, ServerConfigurationManager); - serviceCollection.AddSingleton(UserViewManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -962,7 +959,7 @@ namespace Emby.Server.Implementations BaseItem.UserDataManager = UserDataManager; BaseItem.ChannelManager = ChannelManager; Video.LiveTvManager = LiveTvManager; - Folder.UserViewManager = UserViewManager; + Folder.UserViewManager = Resolve(); UserView.TVSeriesManager = TVSeriesManager; UserView.CollectionManager = CollectionManager; BaseItem.MediaSourceManager = MediaSourceManager; From 3d5b4f869c9edb1e297b89b82221ee837ac6330e Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 13:16:41 -0400 Subject: [PATCH 067/517] Register ILiveTvManager and IPlaylistManager correctly --- Emby.Server.Implementations/ApplicationHost.cs | 6 +++--- Emby.Server.Implementations/LiveTv/LiveTvManager.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index aa1e9ab9d4..94d656e16c 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -797,10 +797,9 @@ namespace Emby.Server.Implementations CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager); serviceCollection.AddSingleton(CollectionManager); - serviceCollection.AddSingleton(typeof(IPlaylistManager), typeof(PlaylistManager)); + serviceCollection.AddSingleton(); - LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, LoggerFactory, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, FileSystemManager, () => ChannelManager); - serviceCollection.AddSingleton(LiveTvManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -833,6 +832,7 @@ namespace Emby.Server.Implementations /// public void InitializeServices() { + LiveTvManager = Resolve(); NotificationManager = Resolve(); HttpServer = Resolve(); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index b64fe8634c..eabc207867 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -49,7 +49,7 @@ namespace Emby.Server.Implementations.LiveTv private readonly ILibraryManager _libraryManager; private readonly ITaskManager _taskManager; private readonly IJsonSerializer _jsonSerializer; - private readonly Func _channelManager; + private readonly IChannelManager _channelManager; private readonly IDtoService _dtoService; private readonly ILocalizationManager _localization; @@ -76,7 +76,7 @@ namespace Emby.Server.Implementations.LiveTv ILocalizationManager localization, IJsonSerializer jsonSerializer, IFileSystem fileSystem, - Func channelManager) + IChannelManager channelManager) { _config = config; _logger = loggerFactory.CreateLogger(nameof(LiveTvManager)); @@ -2482,7 +2482,7 @@ namespace Emby.Server.Implementations.LiveTv .OrderBy(i => i.SortName) .ToList(); - folders.AddRange(_channelManager().GetChannelsInternal(new MediaBrowser.Model.Channels.ChannelQuery + folders.AddRange(_channelManager.GetChannelsInternal(new MediaBrowser.Model.Channels.ChannelQuery { UserId = user.Id, IsRecordingsFolder = true, From bb3db9e845208984a9b2093d81642cc0efc844a0 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 13:56:01 -0400 Subject: [PATCH 068/517] Register ISessionManager, IDlnaManager and ICollectionManager correctly; replace private properties with fields --- .../ApplicationHost.cs | 69 +++++++------------ 1 file changed, 25 insertions(+), 44 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 94d656e16c..48414e26e1 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -120,6 +120,10 @@ namespace Emby.Server.Implementations { private SqliteUserRepository _userRepository; private SqliteDisplayPreferencesRepository _displayPreferencesRepository; + private ISessionManager _sessionManager; + private ILiveTvManager _liveTvManager; + private INotificationManager _notificationManager; + private IHttpServer _httpServer; /// /// Gets a value indicating whether this instance can self restart. @@ -266,11 +270,7 @@ namespace Emby.Server.Implementations /// The provider manager. private IProviderManager ProviderManager { get; set; } - /// - /// Gets or sets the HTTP server. - /// - /// The HTTP server. - private IHttpServer HttpServer { get; set; } + private IDtoService DtoService { get; set; } @@ -282,10 +282,6 @@ namespace Emby.Server.Implementations /// The media encoder. private IMediaEncoder MediaEncoder { get; set; } - private ISessionManager SessionManager { get; set; } - - private ILiveTvManager LiveTvManager { get; set; } - public LocalizationManager LocalizationManager { get; set; } private IChannelManager ChannelManager { get; set; } @@ -298,7 +294,7 @@ namespace Emby.Server.Implementations internal SqliteItemRepository ItemRepository { get; set; } - private INotificationManager NotificationManager { get; set; } + private ISubtitleManager SubtitleManager { get; set; } @@ -308,8 +304,6 @@ namespace Emby.Server.Implementations private ITVSeriesManager TVSeriesManager { get; set; } - private ICollectionManager CollectionManager { get; set; } - private IMediaSourceManager MediaSourceManager { get; set; } /// @@ -541,7 +535,7 @@ namespace Emby.Server.Implementations Logger.LogInformation("Executed all pre-startup entry points in {Elapsed:g}", stopWatch.Elapsed); Logger.LogInformation("Core startup complete"); - HttpServer.GlobalResponse = null; + _httpServer.GlobalResponse = null; stopWatch.Restart(); await Task.WhenAll(StartEntryPoints(entryPoints, false)).ConfigureAwait(false); @@ -609,7 +603,7 @@ namespace Emby.Server.Implementations return; } - await HttpServer.ProcessWebSocketRequest(context).ConfigureAwait(false); + await _httpServer.ProcessWebSocketRequest(context).ConfigureAwait(false); } public async Task ExecuteHttpHandlerAsync(HttpContext context, Func next) @@ -625,7 +619,7 @@ namespace Emby.Server.Implementations var localPath = context.Request.Path.ToString(); var req = new WebSocketSharpRequest(request, response, request.Path, LoggerFactory.CreateLogger()); - await HttpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false); + await _httpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false); } /// @@ -771,31 +765,17 @@ namespace Emby.Server.Implementations ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer); serviceCollection.AddSingleton(ProviderManager); - DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ProviderManager, this, () => MediaSourceManager, () => LiveTvManager); + DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ProviderManager, this, () => MediaSourceManager, () => _liveTvManager); serviceCollection.AddSingleton(DtoService); ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, ProviderManager); serviceCollection.AddSingleton(ChannelManager); - SessionManager = new SessionManager( - LoggerFactory.CreateLogger(), - UserDataManager, - LibraryManager, - UserManager, - musicManager, - DtoService, - ImageProcessor, - this, - AuthenticationRepository, - DeviceManager, - MediaSourceManager); - serviceCollection.AddSingleton(SessionManager); + serviceCollection.AddSingleton(); - serviceCollection.AddSingleton( - new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LoggerFactory, JsonSerializer, this)); + serviceCollection.AddSingleton(); - CollectionManager = new CollectionManager(LibraryManager, ApplicationPaths, LocalizationManager, FileSystemManager, LibraryMonitor, LoggerFactory, ProviderManager); - serviceCollection.AddSingleton(CollectionManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -832,9 +812,10 @@ namespace Emby.Server.Implementations /// public void InitializeServices() { - LiveTvManager = Resolve(); - NotificationManager = Resolve(); - HttpServer = Resolve(); + _sessionManager = Resolve(); + _liveTvManager = Resolve(); + _notificationManager = Resolve(); + _httpServer = Resolve(); ((ActivityRepository)Resolve()).Initialize(); _displayPreferencesRepository.Initialize(); @@ -958,10 +939,10 @@ namespace Emby.Server.Implementations BaseItem.FileSystem = FileSystemManager; BaseItem.UserDataManager = UserDataManager; BaseItem.ChannelManager = ChannelManager; - Video.LiveTvManager = LiveTvManager; + Video.LiveTvManager = _liveTvManager; Folder.UserViewManager = Resolve(); UserView.TVSeriesManager = TVSeriesManager; - UserView.CollectionManager = CollectionManager; + UserView.CollectionManager = Resolve(); BaseItem.MediaSourceManager = MediaSourceManager; CollectionFolder.XmlSerializer = XmlSerializer; CollectionFolder.JsonSerializer = JsonSerializer; @@ -1024,7 +1005,7 @@ namespace Emby.Server.Implementations .Where(i => i != null) .ToArray(); - HttpServer.Init(GetExportTypes(), GetExports(), GetUrlPrefixes()); + _httpServer.Init(GetExportTypes(), GetExports(), GetUrlPrefixes()); LibraryManager.AddParts( GetExports(), @@ -1040,7 +1021,7 @@ namespace Emby.Server.Implementations GetExports(), GetExports()); - LiveTvManager.AddParts(GetExports(), GetExports(), GetExports()); + _liveTvManager.AddParts(GetExports(), GetExports(), GetExports()); SubtitleManager.AddParts(GetExports()); @@ -1048,7 +1029,7 @@ namespace Emby.Server.Implementations MediaSourceManager.AddParts(GetExports()); - NotificationManager.AddParts(GetExports(), GetExports()); + _notificationManager.AddParts(GetExports(), GetExports()); UserManager.AddParts(GetExports(), GetExports()); IsoManager.AddParts(GetExports()); @@ -1194,7 +1175,7 @@ namespace Emby.Server.Implementations } } - if (!HttpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase)) + if (!_httpServer.UrlPrefixes.SequenceEqual(GetUrlPrefixes(), StringComparer.OrdinalIgnoreCase)) { requiresRestart = true; } @@ -1254,7 +1235,7 @@ namespace Emby.Server.Implementations { try { - await SessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false); + await _sessionManager.SendServerRestartNotification(CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { @@ -1618,7 +1599,7 @@ namespace Emby.Server.Implementations try { - await SessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false); + await _sessionManager.SendServerShutdownNotification(CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { From f78423bd494d2439191e57705ec4031cb211e4d4 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 14:32:35 -0400 Subject: [PATCH 069/517] Register IChannerManager correctly --- Emby.Server.Implementations/ApplicationHost.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 48414e26e1..f437390c0e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -120,6 +120,7 @@ namespace Emby.Server.Implementations { private SqliteUserRepository _userRepository; private SqliteDisplayPreferencesRepository _displayPreferencesRepository; + private IChannelManager _channelManager; private ISessionManager _sessionManager; private ILiveTvManager _liveTvManager; private INotificationManager _notificationManager; @@ -284,7 +285,7 @@ namespace Emby.Server.Implementations public LocalizationManager LocalizationManager { get; set; } - private IChannelManager ChannelManager { get; set; } + /// /// Gets or sets the user data repository. @@ -768,8 +769,7 @@ namespace Emby.Server.Implementations DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ProviderManager, this, () => MediaSourceManager, () => _liveTvManager); serviceCollection.AddSingleton(DtoService); - ChannelManager = new ChannelManager(UserManager, DtoService, LibraryManager, LoggerFactory, ServerConfigurationManager, FileSystemManager, UserDataManager, JsonSerializer, ProviderManager); - serviceCollection.AddSingleton(ChannelManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -812,6 +812,7 @@ namespace Emby.Server.Implementations /// public void InitializeServices() { + _channelManager = Resolve(); _sessionManager = Resolve(); _liveTvManager = Resolve(); _notificationManager = Resolve(); @@ -938,7 +939,7 @@ namespace Emby.Server.Implementations User.UserManager = UserManager; BaseItem.FileSystem = FileSystemManager; BaseItem.UserDataManager = UserDataManager; - BaseItem.ChannelManager = ChannelManager; + BaseItem.ChannelManager = _channelManager; Video.LiveTvManager = _liveTvManager; Folder.UserViewManager = Resolve(); UserView.TVSeriesManager = TVSeriesManager; @@ -1025,7 +1026,7 @@ namespace Emby.Server.Implementations SubtitleManager.AddParts(GetExports()); - ChannelManager.AddParts(GetExports()); + _channelManager.AddParts(GetExports()); MediaSourceManager.AddParts(GetExports()); From cb2d99e8318d6831b8c7ba80997c172e72a6ee95 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 14:40:04 -0400 Subject: [PATCH 070/517] Construct LiveTvDtoService and LiveTvManager correctly --- .../ApplicationHost.cs | 1 + .../LiveTv/LiveTvDtoService.cs | 5 ++--- .../LiveTv/LiveTvManager.cs | 21 +++++++------------ 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index f437390c0e..e10627ad11 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -779,6 +779,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); diff --git a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs index 6e903a18ef..55300c9671 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -24,7 +24,6 @@ namespace Emby.Server.Implementations.LiveTv { private readonly ILogger _logger; private readonly IImageProcessor _imageProcessor; - private readonly IDtoService _dtoService; private readonly IApplicationHost _appHost; private readonly ILibraryManager _libraryManager; @@ -32,13 +31,13 @@ namespace Emby.Server.Implementations.LiveTv public LiveTvDtoService( IDtoService dtoService, IImageProcessor imageProcessor, - ILoggerFactory loggerFactory, + ILogger logger, IApplicationHost appHost, ILibraryManager libraryManager) { _dtoService = dtoService; _imageProcessor = imageProcessor; - _logger = loggerFactory.CreateLogger(nameof(LiveTvDtoService)); + _logger = logger; _appHost = appHost; _libraryManager = libraryManager; } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index eabc207867..d8ff8a72fa 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -45,29 +45,24 @@ namespace Emby.Server.Implementations.LiveTv private readonly ILogger _logger; private readonly IItemRepository _itemRepo; private readonly IUserManager _userManager; + private readonly IDtoService _dtoService; private readonly IUserDataManager _userDataManager; private readonly ILibraryManager _libraryManager; private readonly ITaskManager _taskManager; + private readonly ILocalizationManager _localization; private readonly IJsonSerializer _jsonSerializer; + private readonly IFileSystem _fileSystem; private readonly IChannelManager _channelManager; - - private readonly IDtoService _dtoService; - private readonly ILocalizationManager _localization; - private readonly LiveTvDtoService _tvDtoService; private ILiveTvService[] _services = Array.Empty(); - private ITunerHost[] _tunerHosts = Array.Empty(); private IListingsProvider[] _listingProviders = Array.Empty(); - private readonly IFileSystem _fileSystem; public LiveTvManager( - IServerApplicationHost appHost, IServerConfigurationManager config, - ILoggerFactory loggerFactory, + ILogger logger, IItemRepository itemRepo, - IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, @@ -76,10 +71,11 @@ namespace Emby.Server.Implementations.LiveTv ILocalizationManager localization, IJsonSerializer jsonSerializer, IFileSystem fileSystem, - IChannelManager channelManager) + IChannelManager channelManager, + LiveTvDtoService liveTvDtoService) { _config = config; - _logger = loggerFactory.CreateLogger(nameof(LiveTvManager)); + _logger = logger; _itemRepo = itemRepo; _userManager = userManager; _libraryManager = libraryManager; @@ -90,8 +86,7 @@ namespace Emby.Server.Implementations.LiveTv _dtoService = dtoService; _userDataManager = userDataManager; _channelManager = channelManager; - - _tvDtoService = new LiveTvDtoService(dtoService, imageProcessor, loggerFactory, appHost, _libraryManager); + _tvDtoService = liveTvDtoService; } public event EventHandler> SeriesTimerCancelled; From 75b05ca1e6dce73c2d419dd83cbc5f9693688faa Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 14:41:03 -0400 Subject: [PATCH 071/517] Register and construct DtoService correctly --- .../ApplicationHost.cs | 11 +++---- Emby.Server.Implementations/Dto/DtoService.cs | 30 ++++++++++--------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index e10627ad11..44056dc9e5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -271,10 +271,6 @@ namespace Emby.Server.Implementations /// The provider manager. private IProviderManager ProviderManager { get; set; } - - - private IDtoService DtoService { get; set; } - public IImageProcessor ImageProcessor { get; set; } /// @@ -711,7 +707,7 @@ namespace Emby.Server.Implementations XmlSerializer, NetworkManager, () => ImageProcessor, - () => DtoService, + Resolve, this, JsonSerializer, FileSystemManager, @@ -766,8 +762,9 @@ namespace Emby.Server.Implementations ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer); serviceCollection.AddSingleton(ProviderManager); - DtoService = new DtoService(LoggerFactory, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ProviderManager, this, () => MediaSourceManager, () => _liveTvManager); - serviceCollection.AddSingleton(DtoService); + // TODO: Refactor to eliminate circular dependency here so Lazy<> isn't required + serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 65711e89d8..001cfe5dbb 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -38,21 +38,23 @@ namespace Emby.Server.Implementations.Dto private readonly IProviderManager _providerManager; private readonly IApplicationHost _appHost; - private readonly Func _mediaSourceManager; - private readonly Func _livetvManager; + private readonly IMediaSourceManager _mediaSourceManager; + private readonly Lazy _livetvManagerLazy; + + private ILiveTvManager LivetvManager => _livetvManagerLazy.Value; public DtoService( - ILoggerFactory loggerFactory, + ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IProviderManager providerManager, IApplicationHost appHost, - Func mediaSourceManager, - Func livetvManager) + IMediaSourceManager mediaSourceManager, + Lazy livetvManager) { - _logger = loggerFactory.CreateLogger(nameof(DtoService)); + _logger = logger; _libraryManager = libraryManager; _userDataRepository = userDataRepository; _itemRepo = itemRepo; @@ -60,7 +62,7 @@ namespace Emby.Server.Implementations.Dto _providerManager = providerManager; _appHost = appHost; _mediaSourceManager = mediaSourceManager; - _livetvManager = livetvManager; + _livetvManagerLazy = livetvManager; } /// @@ -125,12 +127,12 @@ namespace Emby.Server.Implementations.Dto if (programTuples.Count > 0) { - _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult(); + LivetvManager.AddInfoToProgramDto(programTuples, options.Fields, user).GetAwaiter().GetResult(); } if (channelTuples.Count > 0) { - _livetvManager().AddChannelInfo(channelTuples, options, user); + LivetvManager.AddChannelInfo(channelTuples, options, user); } return returnItems; @@ -142,12 +144,12 @@ namespace Emby.Server.Implementations.Dto if (item is LiveTvChannel tvChannel) { var list = new List<(BaseItemDto, LiveTvChannel)>(1) { (dto, tvChannel) }; - _livetvManager().AddChannelInfo(list, options, user); + LivetvManager.AddChannelInfo(list, options, user); } else if (item is LiveTvProgram) { var list = new List<(BaseItem, BaseItemDto)>(1) { (item, dto) }; - var task = _livetvManager().AddInfoToProgramDto(list, options.Fields, user); + var task = LivetvManager.AddInfoToProgramDto(list, options.Fields, user); Task.WaitAll(task); } @@ -223,7 +225,7 @@ namespace Emby.Server.Implementations.Dto if (item is IHasMediaSources && options.ContainsField(ItemFields.MediaSources)) { - dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(item, true, user).ToArray(); + dto.MediaSources = _mediaSourceManager.GetStaticMediaSources(item, true, user).ToArray(); NormalizeMediaSourceContainers(dto); } @@ -254,7 +256,7 @@ namespace Emby.Server.Implementations.Dto dto.Etag = item.GetEtag(user); } - var liveTvManager = _livetvManager(); + var liveTvManager = LivetvManager; var activeRecording = liveTvManager.GetActiveRecordingInfo(item.Path); if (activeRecording != null) { @@ -1045,7 +1047,7 @@ namespace Emby.Server.Implementations.Dto } else { - mediaStreams = _mediaSourceManager().GetStaticMediaSources(item, true)[0].MediaStreams.ToArray(); + mediaStreams = _mediaSourceManager.GetStaticMediaSources(item, true)[0].MediaStreams.ToArray(); } dto.MediaStreams = mediaStreams; From 51b9a6e94b06db6ae4b21cf2372287a98778a075 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 14:56:50 -0400 Subject: [PATCH 072/517] Register IProviderManager correctly --- .../ApplicationHost.cs | 15 ++-- Emby.Server.Implementations/Dto/DtoService.cs | 8 +-- .../Manager/ProviderManager.cs | 71 ++++++++----------- 3 files changed, 39 insertions(+), 55 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 44056dc9e5..8a3398e01a 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -265,12 +265,6 @@ namespace Emby.Server.Implementations /// The directory watchers. private ILibraryMonitor LibraryMonitor { get; set; } - /// - /// Gets or sets the provider manager. - /// - /// The provider manager. - private IProviderManager ProviderManager { get; set; } - public IImageProcessor ImageProcessor { get; set; } /// @@ -726,7 +720,7 @@ namespace Emby.Server.Implementations StartupOptions.FFmpegPath); serviceCollection.AddSingleton(MediaEncoder); - LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager, Resolve, MediaEncoder); + LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, Resolve, Resolve, MediaEncoder); serviceCollection.AddSingleton(LibraryManager); var musicManager = new MusicManager(LibraryManager); @@ -759,8 +753,7 @@ namespace Emby.Server.Implementations SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager); serviceCollection.AddSingleton(SubtitleManager); - ProviderManager = new ProviderManager(HttpClient, SubtitleManager, ServerConfigurationManager, LibraryMonitor, LoggerFactory, FileSystemManager, ApplicationPaths, () => LibraryManager, JsonSerializer); - serviceCollection.AddSingleton(ProviderManager); + serviceCollection.AddSingleton(); // TODO: Refactor to eliminate circular dependency here so Lazy<> isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); @@ -931,7 +924,7 @@ namespace Emby.Server.Implementations BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem"); BaseItem.ConfigurationManager = ServerConfigurationManager; BaseItem.LibraryManager = LibraryManager; - BaseItem.ProviderManager = ProviderManager; + BaseItem.ProviderManager = Resolve(); BaseItem.LocalizationManager = LocalizationManager; BaseItem.ItemRepository = ItemRepository; User.UserManager = UserManager; @@ -1013,7 +1006,7 @@ namespace Emby.Server.Implementations GetExports(), GetExports()); - ProviderManager.AddParts( + Resolve().AddParts( GetExports(), GetExports(), GetExports(), diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 001cfe5dbb..c8ea861ce4 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -39,9 +39,9 @@ namespace Emby.Server.Implementations.Dto private readonly IApplicationHost _appHost; private readonly IMediaSourceManager _mediaSourceManager; - private readonly Lazy _livetvManagerLazy; + private readonly Lazy _livetvManagerFactory; - private ILiveTvManager LivetvManager => _livetvManagerLazy.Value; + private ILiveTvManager LivetvManager => _livetvManagerFactory.Value; public DtoService( ILogger logger, @@ -52,7 +52,7 @@ namespace Emby.Server.Implementations.Dto IProviderManager providerManager, IApplicationHost appHost, IMediaSourceManager mediaSourceManager, - Lazy livetvManager) + Lazy livetvManagerFactory) { _logger = logger; _libraryManager = libraryManager; @@ -62,7 +62,7 @@ namespace Emby.Server.Implementations.Dto _providerManager = providerManager; _appHost = appHost; _mediaSourceManager = mediaSourceManager; - _livetvManagerLazy = livetvManager; + _livetvManagerFactory = livetvManagerFactory; } /// diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 7125f34c55..337bc37eb9 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -36,60 +36,51 @@ namespace MediaBrowser.Providers.Manager /// public class ProviderManager : IProviderManager, IDisposable { - /// - /// The _logger - /// private readonly ILogger _logger; - - /// - /// The _HTTP client - /// private readonly IHttpClient _httpClient; - - /// - /// The _directory watchers - /// private readonly ILibraryMonitor _libraryMonitor; - - /// - /// Gets or sets the configuration manager. - /// - /// The configuration manager. - private IServerConfigurationManager ConfigurationManager { get; set; } + private readonly IFileSystem _fileSystem; + private readonly IServerApplicationPaths _appPaths; + private readonly IJsonSerializer _json; + private readonly ILibraryManager _libraryManager; + private readonly ISubtitleManager _subtitleManager; + private readonly IServerConfigurationManager _configurationManager; private IImageProvider[] ImageProviders { get; set; } - private readonly IFileSystem _fileSystem; - private IMetadataService[] _metadataServices = { }; private IMetadataProvider[] _metadataProviders = { }; private IEnumerable _savers; - private readonly IServerApplicationPaths _appPaths; - private readonly IJsonSerializer _json; private IExternalId[] _externalIds; - private readonly Func _libraryManagerFactory; private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource(); public event EventHandler> RefreshStarted; public event EventHandler> RefreshCompleted; public event EventHandler>> RefreshProgress; - private ISubtitleManager _subtitleManager; - /// /// Initializes a new instance of the class. /// - public ProviderManager(IHttpClient httpClient, ISubtitleManager subtitleManager, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILoggerFactory loggerFactory, IFileSystem fileSystem, IServerApplicationPaths appPaths, Func libraryManagerFactory, IJsonSerializer json) + public ProviderManager( + IHttpClient httpClient, + ISubtitleManager subtitleManager, + IServerConfigurationManager configurationManager, + ILibraryMonitor libraryMonitor, + ILogger logger, + IFileSystem fileSystem, + IServerApplicationPaths appPaths, + ILibraryManager libraryManager, + IJsonSerializer json) { - _logger = loggerFactory.CreateLogger("ProviderManager"); + _logger = logger; _httpClient = httpClient; - ConfigurationManager = configurationManager; + _configurationManager = configurationManager; _libraryMonitor = libraryMonitor; _fileSystem = fileSystem; _appPaths = appPaths; - _libraryManagerFactory = libraryManagerFactory; + _libraryManager = libraryManager; _json = json; _subtitleManager = subtitleManager; } @@ -176,7 +167,7 @@ namespace MediaBrowser.Providers.Manager public Task SaveImage(BaseItem item, Stream source, string mimeType, ImageType type, int? imageIndex, CancellationToken cancellationToken) { - return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken); + return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken); } public Task SaveImage(BaseItem item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken) @@ -188,7 +179,7 @@ namespace MediaBrowser.Providers.Manager var fileStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, IODefaults.FileStreamBufferSize, true); - return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken); + return new ImageSaver(_configurationManager, _libraryMonitor, _fileSystem, _logger).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken); } public async Task> GetAvailableRemoteImages(BaseItem item, RemoteImageQuery query, CancellationToken cancellationToken) @@ -273,7 +264,7 @@ namespace MediaBrowser.Providers.Manager public IEnumerable GetImageProviders(BaseItem item, ImageRefreshOptions refreshOptions) { - return GetImageProviders(item, _libraryManagerFactory().GetLibraryOptions(item), GetMetadataOptions(item), refreshOptions, false); + return GetImageProviders(item, _libraryManager.GetLibraryOptions(item), GetMetadataOptions(item), refreshOptions, false); } private IEnumerable GetImageProviders(BaseItem item, LibraryOptions libraryOptions, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled) @@ -328,7 +319,7 @@ namespace MediaBrowser.Providers.Manager private IEnumerable GetRemoteImageProviders(BaseItem item, bool includeDisabled) { var options = GetMetadataOptions(item); - var libraryOptions = _libraryManagerFactory().GetLibraryOptions(item); + var libraryOptions = _libraryManager.GetLibraryOptions(item); return GetImageProviders(item, libraryOptions, options, new ImageRefreshOptions( @@ -593,7 +584,7 @@ namespace MediaBrowser.Providers.Manager { var type = item.GetType().Name; - return ConfigurationManager.Configuration.MetadataOptions + return _configurationManager.Configuration.MetadataOptions .FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ?? new MetadataOptions(); } @@ -623,7 +614,7 @@ namespace MediaBrowser.Providers.Manager /// Task. private void SaveMetadata(BaseItem item, ItemUpdateType updateType, IEnumerable savers) { - var libraryOptions = _libraryManagerFactory().GetLibraryOptions(item); + var libraryOptions = _libraryManager.GetLibraryOptions(item); foreach (var saver in savers.Where(i => IsSaverEnabledForItem(i, item, libraryOptions, updateType, false))) { @@ -743,7 +734,7 @@ namespace MediaBrowser.Providers.Manager if (!searchInfo.ItemId.Equals(Guid.Empty)) { - referenceItem = _libraryManagerFactory().GetItemById(searchInfo.ItemId); + referenceItem = _libraryManager.GetItemById(searchInfo.ItemId); } return GetRemoteSearchResults(searchInfo, referenceItem, cancellationToken); @@ -771,7 +762,7 @@ namespace MediaBrowser.Providers.Manager } else { - libraryOptions = _libraryManagerFactory().GetLibraryOptions(referenceItem); + libraryOptions = _libraryManager.GetLibraryOptions(referenceItem); } var options = GetMetadataOptions(referenceItem); @@ -786,11 +777,11 @@ namespace MediaBrowser.Providers.Manager if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataLanguage)) { - searchInfo.SearchInfo.MetadataLanguage = ConfigurationManager.Configuration.PreferredMetadataLanguage; + searchInfo.SearchInfo.MetadataLanguage = _configurationManager.Configuration.PreferredMetadataLanguage; } if (string.IsNullOrWhiteSpace(searchInfo.SearchInfo.MetadataCountryCode)) { - searchInfo.SearchInfo.MetadataCountryCode = ConfigurationManager.Configuration.MetadataCountryCode; + searchInfo.SearchInfo.MetadataCountryCode = _configurationManager.Configuration.MetadataCountryCode; } var resultList = new List(); @@ -1010,7 +1001,7 @@ namespace MediaBrowser.Providers.Manager private async Task StartProcessingRefreshQueue() { - var libraryManager = _libraryManagerFactory(); + var libraryManager = _libraryManager; if (_disposed) { @@ -1088,7 +1079,7 @@ namespace MediaBrowser.Providers.Manager private async Task RefreshArtist(MusicArtist item, MetadataRefreshOptions options, CancellationToken cancellationToken) { - var albums = _libraryManagerFactory() + var albums = _libraryManager .GetItemList(new InternalItemsQuery { IncludeItemTypes = new[] { nameof(MusicAlbum) }, From 0ce82ab33288727fcbb400d72db62df440ef104d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 15:05:50 -0400 Subject: [PATCH 073/517] Remove unnecessary fields in ApplicationHost --- .../ApplicationHost.cs | 21 ++++++++----------- Jellyfin.Server/Program.cs | 1 - 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8a3398e01a..81736f053d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -120,9 +120,7 @@ namespace Emby.Server.Implementations { private SqliteUserRepository _userRepository; private SqliteDisplayPreferencesRepository _displayPreferencesRepository; - private IChannelManager _channelManager; private ISessionManager _sessionManager; - private ILiveTvManager _liveTvManager; private INotificationManager _notificationManager; private IHttpServer _httpServer; @@ -803,10 +801,7 @@ namespace Emby.Server.Implementations /// public void InitializeServices() { - _channelManager = Resolve(); _sessionManager = Resolve(); - _liveTvManager = Resolve(); - _notificationManager = Resolve(); _httpServer = Resolve(); ((ActivityRepository)Resolve()).Initialize(); @@ -821,6 +816,8 @@ namespace Emby.Server.Implementations ((UserDataManager)UserDataManager).Repository = userDataRepo; ItemRepository.Initialize(userDataRepo, UserManager); ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; + + FindParts(); } public static void LogEnvironmentInfo(ILogger logger, IApplicationPaths appPaths) @@ -930,8 +927,8 @@ namespace Emby.Server.Implementations User.UserManager = UserManager; BaseItem.FileSystem = FileSystemManager; BaseItem.UserDataManager = UserDataManager; - BaseItem.ChannelManager = _channelManager; - Video.LiveTvManager = _liveTvManager; + BaseItem.ChannelManager = Resolve(); + Video.LiveTvManager = Resolve(); Folder.UserViewManager = Resolve(); UserView.TVSeriesManager = TVSeriesManager; UserView.CollectionManager = Resolve(); @@ -978,9 +975,9 @@ namespace Emby.Server.Implementations } /// - /// Finds the parts. + /// Finds plugin components and register them with the appropriate services. /// - public void FindParts() + private void FindParts() { InstallationManager = ServiceProvider.GetService(); InstallationManager.PluginInstalled += PluginInstalled; @@ -1013,15 +1010,15 @@ namespace Emby.Server.Implementations GetExports(), GetExports()); - _liveTvManager.AddParts(GetExports(), GetExports(), GetExports()); + Resolve().AddParts(GetExports(), GetExports(), GetExports()); SubtitleManager.AddParts(GetExports()); - _channelManager.AddParts(GetExports()); + Resolve().AddParts(GetExports()); MediaSourceManager.AddParts(GetExports()); - _notificationManager.AddParts(GetExports(), GetExports()); + Resolve().AddParts(GetExports(), GetExports()); UserManager.AddParts(GetExports(), GetExports()); IsoManager.AddParts(GetExports()); diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 4abdd59aaf..6be9ba4f2d 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -210,7 +210,6 @@ namespace Jellyfin.Server // Re-use the web host service provider in the app host since ASP.NET doesn't allow a custom service collection. appHost.ServiceProvider = webHost.Services; appHost.InitializeServices(); - appHost.FindParts(); Migrations.MigrationRunner.Run(appHost, _loggerFactory); try From 3d8b81039d0f735a893fde8e0bef4bdfefd2db8a Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 15:08:04 -0400 Subject: [PATCH 074/517] Log refresh progress at Debug level --- MediaBrowser.Providers/Manager/ProviderManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 337bc37eb9..cfff897672 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -958,7 +958,7 @@ namespace MediaBrowser.Providers.Manager public void OnRefreshProgress(BaseItem item, double progress) { var id = item.Id; - _logger.LogInformation("OnRefreshProgress {0} {1}", id.ToString("N", CultureInfo.InvariantCulture), progress); + _logger.LogDebug("OnRefreshProgress {0} {1}", id.ToString("N", CultureInfo.InvariantCulture), progress); // TODO: Need to hunt down the conditions for this happening _activeRefreshes.AddOrUpdate( From dd5a55aeba0ad90c277d0acb243558e3a37d2506 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 15:12:02 -0400 Subject: [PATCH 075/517] Register ISubtitleManager correctly --- Emby.Server.Implementations/ApplicationHost.cs | 10 ++-------- MediaBrowser.Providers/Subtitles/SubtitleManager.cs | 8 ++++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 81736f053d..6db832b798 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -121,7 +121,6 @@ namespace Emby.Server.Implementations private SqliteUserRepository _userRepository; private SqliteDisplayPreferencesRepository _displayPreferencesRepository; private ISessionManager _sessionManager; - private INotificationManager _notificationManager; private IHttpServer _httpServer; /// @@ -283,10 +282,6 @@ namespace Emby.Server.Implementations internal SqliteItemRepository ItemRepository { get; set; } - - - private ISubtitleManager SubtitleManager { get; set; } - private IDeviceManager DeviceManager { get; set; } private IAuthenticationRepository AuthenticationRepository { get; set; } @@ -748,8 +743,7 @@ namespace Emby.Server.Implementations MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder); serviceCollection.AddSingleton(MediaSourceManager); - SubtitleManager = new SubtitleManager(LoggerFactory, FileSystemManager, LibraryMonitor, MediaSourceManager, LocalizationManager); - serviceCollection.AddSingleton(SubtitleManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -1012,7 +1006,7 @@ namespace Emby.Server.Implementations Resolve().AddParts(GetExports(), GetExports(), GetExports()); - SubtitleManager.AddParts(GetExports()); + Resolve().AddParts(GetExports()); Resolve().AddParts(GetExports()); diff --git a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs index 583c7e8ea4..127d29c04e 100644 --- a/MediaBrowser.Providers/Subtitles/SubtitleManager.cs +++ b/MediaBrowser.Providers/Subtitles/SubtitleManager.cs @@ -25,22 +25,22 @@ namespace MediaBrowser.Providers.Subtitles { public class SubtitleManager : ISubtitleManager { - private ISubtitleProvider[] _subtitleProviders; private readonly ILogger _logger; private readonly IFileSystem _fileSystem; private readonly ILibraryMonitor _monitor; private readonly IMediaSourceManager _mediaSourceManager; + private readonly ILocalizationManager _localization; - private ILocalizationManager _localization; + private ISubtitleProvider[] _subtitleProviders; public SubtitleManager( - ILoggerFactory loggerFactory, + ILogger logger, IFileSystem fileSystem, ILibraryMonitor monitor, IMediaSourceManager mediaSourceManager, ILocalizationManager localizationManager) { - _logger = loggerFactory.CreateLogger(nameof(SubtitleManager)); + _logger = logger; _fileSystem = fileSystem; _monitor = monitor; _mediaSourceManager = mediaSourceManager; From 573da63d41e47af7cdd54cb1f5017b0317a6ba64 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 15:28:21 -0400 Subject: [PATCH 076/517] Register and construct IMediaSourceManager correctly --- .../ApplicationHost.cs | 11 ++++------ .../Library/MediaSourceManager.cs | 22 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 6db832b798..0f1b24bbc2 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -288,8 +288,6 @@ namespace Emby.Server.Implementations private ITVSeriesManager TVSeriesManager { get; set; } - private IMediaSourceManager MediaSourceManager { get; set; } - /// /// Gets the installation manager. /// @@ -740,14 +738,13 @@ namespace Emby.Server.Implementations DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager); serviceCollection.AddSingleton(DeviceManager); - MediaSourceManager = new MediaSourceManager(ItemRepository, ApplicationPaths, LocalizationManager, UserManager, LibraryManager, LoggerFactory, JsonSerializer, FileSystemManager, UserDataManager, () => MediaEncoder); - serviceCollection.AddSingleton(MediaSourceManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - // TODO: Refactor to eliminate circular dependency here so Lazy<> isn't required + // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); serviceCollection.AddSingleton(); @@ -926,7 +923,7 @@ namespace Emby.Server.Implementations Folder.UserViewManager = Resolve(); UserView.TVSeriesManager = TVSeriesManager; UserView.CollectionManager = Resolve(); - BaseItem.MediaSourceManager = MediaSourceManager; + BaseItem.MediaSourceManager = Resolve(); CollectionFolder.XmlSerializer = XmlSerializer; CollectionFolder.JsonSerializer = JsonSerializer; CollectionFolder.ApplicationHost = this; @@ -1010,7 +1007,7 @@ namespace Emby.Server.Implementations Resolve().AddParts(GetExports()); - MediaSourceManager.AddParts(GetExports()); + Resolve().AddParts(GetExports()); Resolve().AddParts(GetExports(), GetExports()); UserManager.AddParts(GetExports(), GetExports()); diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 70d5bd9f4e..01fe98f3af 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -33,13 +33,13 @@ namespace Emby.Server.Implementations.Library private readonly ILibraryManager _libraryManager; private readonly IJsonSerializer _jsonSerializer; private readonly IFileSystem _fileSystem; - - private IMediaSourceProvider[] _providers; private readonly ILogger _logger; private readonly IUserDataManager _userDataManager; - private readonly Func _mediaEncoder; - private ILocalizationManager _localizationManager; - private IApplicationPaths _appPaths; + private readonly IMediaEncoder _mediaEncoder; + private readonly ILocalizationManager _localizationManager; + private readonly IApplicationPaths _appPaths; + + private IMediaSourceProvider[] _providers; public MediaSourceManager( IItemRepository itemRepo, @@ -47,16 +47,16 @@ namespace Emby.Server.Implementations.Library ILocalizationManager localizationManager, IUserManager userManager, ILibraryManager libraryManager, - ILoggerFactory loggerFactory, + ILogger logger, IJsonSerializer jsonSerializer, IFileSystem fileSystem, IUserDataManager userDataManager, - Func mediaEncoder) + IMediaEncoder mediaEncoder) { _itemRepo = itemRepo; _userManager = userManager; _libraryManager = libraryManager; - _logger = loggerFactory.CreateLogger(nameof(MediaSourceManager)); + _logger = logger; _jsonSerializer = jsonSerializer; _fileSystem = fileSystem; _userDataManager = userDataManager; @@ -496,7 +496,7 @@ namespace Emby.Server.Implementations.Library // hack - these two values were taken from LiveTVMediaSourceProvider string cacheKey = request.OpenToken; - await new LiveStreamHelper(_mediaEncoder(), _logger, _jsonSerializer, _appPaths) + await new LiveStreamHelper(_mediaEncoder, _logger, _jsonSerializer, _appPaths) .AddMediaInfoWithProbe(mediaSource, isAudio, cacheKey, true, cancellationToken) .ConfigureAwait(false); } @@ -621,7 +621,7 @@ namespace Emby.Server.Implementations.Library if (liveStreamInfo is IDirectStreamProvider) { - var info = await _mediaEncoder().GetMediaInfo(new MediaInfoRequest + var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest { MediaSource = mediaSource, ExtractChapters = false, @@ -674,7 +674,7 @@ namespace Emby.Server.Implementations.Library mediaSource.AnalyzeDurationMs = 3000; } - mediaInfo = await _mediaEncoder().GetMediaInfo(new MediaInfoRequest + mediaInfo = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest { MediaSource = mediaSource, MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video, From 7b31b0e322332690fa9bda7d16a5f9a0cdeffa8d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 15:33:23 -0400 Subject: [PATCH 077/517] Inject logger correctly into ActivityManager and ActivityRepository --- Emby.Server.Implementations/Activity/ActivityManager.cs | 4 ++-- Emby.Server.Implementations/Activity/ActivityRepository.cs | 4 ++-- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs index ee10845cfa..34ccd4bba1 100644 --- a/Emby.Server.Implementations/Activity/ActivityManager.cs +++ b/Emby.Server.Implementations/Activity/ActivityManager.cs @@ -18,11 +18,11 @@ namespace Emby.Server.Implementations.Activity private readonly IUserManager _userManager; public ActivityManager( - ILoggerFactory loggerFactory, + ILogger logger, IActivityRepository repo, IUserManager userManager) { - _logger = loggerFactory.CreateLogger(nameof(ActivityManager)); + _logger = logger; _repo = repo; _userManager = userManager; } diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index 7be72319ea..0fd2625217 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -20,8 +20,8 @@ namespace Emby.Server.Implementations.Activity private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); private readonly IFileSystem _fileSystem; - public ActivityRepository(ILoggerFactory loggerFactory, IServerApplicationPaths appPaths, IFileSystem fileSystem) - : base(loggerFactory.CreateLogger(nameof(ActivityRepository))) + public ActivityRepository(ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem) + : base(logger) { DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db"); _fileSystem = fileSystem; diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index ce576a6c3b..42379c73bb 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -471,7 +471,7 @@ namespace MediaBrowser.Controller.MediaEncoding { var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); var outputVideoCodec = GetVideoEncoder(state, encodingOptions); - + var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; if (!hasTextSubs) From 71c84905de8f1c303c991b240d22a2f9616965e8 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 15:40:06 -0400 Subject: [PATCH 078/517] Register IDeviceManager correctly --- Emby.Server.Implementations/ApplicationHost.cs | 5 +---- Emby.Server.Implementations/Devices/DeviceManager.cs | 6 +++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 0f1b24bbc2..9d4964a9e4 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -282,8 +282,6 @@ namespace Emby.Server.Implementations internal SqliteItemRepository ItemRepository { get; set; } - private IDeviceManager DeviceManager { get; set; } - private IAuthenticationRepository AuthenticationRepository { get; set; } private ITVSeriesManager TVSeriesManager { get; set; } @@ -735,8 +733,7 @@ namespace Emby.Server.Implementations TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager); serviceCollection.AddSingleton(TVSeriesManager); - DeviceManager = new DeviceManager(AuthenticationRepository, JsonSerializer, LibraryManager, LocalizationManager, UserManager, FileSystemManager, LibraryMonitor, ServerConfigurationManager); - serviceCollection.AddSingleton(DeviceManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs index adb8e793d2..579cb895e4 100644 --- a/Emby.Server.Implementations/Devices/DeviceManager.cs +++ b/Emby.Server.Implementations/Devices/DeviceManager.cs @@ -38,10 +38,11 @@ namespace Emby.Server.Implementations.Devices private readonly IServerConfigurationManager _config; private readonly ILibraryManager _libraryManager; private readonly ILocalizationManager _localizationManager; - private readonly IAuthenticationRepository _authRepo; + private readonly Dictionary _capabilitiesCache; public event EventHandler>> DeviceOptionsUpdated; + public event EventHandler> CameraImageUploaded; private readonly object _cameraUploadSyncLock = new object(); @@ -65,10 +66,9 @@ namespace Emby.Server.Implementations.Devices _libraryManager = libraryManager; _localizationManager = localizationManager; _authRepo = authRepo; + _capabilitiesCache = new Dictionary(StringComparer.OrdinalIgnoreCase); } - - private Dictionary _capabilitiesCache = new Dictionary(StringComparer.OrdinalIgnoreCase); public void SaveCapabilities(string deviceId, ClientCapabilities capabilities) { var path = Path.Combine(GetDevicePath(deviceId), "capabilities.json"); From 11693d6024f4b8dafb69ac4a4fcb85ee2caad065 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 15:44:44 -0400 Subject: [PATCH 079/517] Register ITvManagerService correctly --- Emby.Server.Implementations/ApplicationHost.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 9d4964a9e4..c5b8878f84 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -272,8 +272,6 @@ namespace Emby.Server.Implementations public LocalizationManager LocalizationManager { get; set; } - - /// /// Gets or sets the user data repository. /// @@ -284,8 +282,6 @@ namespace Emby.Server.Implementations private IAuthenticationRepository AuthenticationRepository { get; set; } - private ITVSeriesManager TVSeriesManager { get; set; } - /// /// Gets the installation manager. /// @@ -730,8 +726,7 @@ namespace Emby.Server.Implementations ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => LibraryManager, () => MediaEncoder); serviceCollection.AddSingleton(ImageProcessor); - TVSeriesManager = new TVSeriesManager(UserManager, UserDataManager, LibraryManager, ServerConfigurationManager); - serviceCollection.AddSingleton(TVSeriesManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -918,7 +913,7 @@ namespace Emby.Server.Implementations BaseItem.ChannelManager = Resolve(); Video.LiveTvManager = Resolve(); Folder.UserViewManager = Resolve(); - UserView.TVSeriesManager = TVSeriesManager; + UserView.TVSeriesManager = Resolve(); UserView.CollectionManager = Resolve(); BaseItem.MediaSourceManager = Resolve(); CollectionFolder.XmlSerializer = XmlSerializer; From efe3ebaab8fbb064652ac4923297f315e4a798e7 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 16:01:10 -0400 Subject: [PATCH 080/517] Eliminate circular dependency between LibraryManager and ImageProcessor --- Emby.Drawing/ImageProcessor.cs | 25 ------------------- Emby.Photos/PhotoProvider.cs | 2 +- .../ApplicationHost.cs | 2 +- MediaBrowser.Api/Images/ImageService.cs | 9 ++++++- .../Drawing/IImageProcessor.cs | 9 ------- 5 files changed, 10 insertions(+), 37 deletions(-) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index eca4b56eb9..a9cab147c8 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -33,7 +33,6 @@ namespace Emby.Drawing private readonly IFileSystem _fileSystem; private readonly IServerApplicationPaths _appPaths; private readonly IImageEncoder _imageEncoder; - private readonly Func _libraryManager; private readonly Func _mediaEncoder; private bool _disposed = false; @@ -45,20 +44,17 @@ namespace Emby.Drawing /// The server application paths. /// The filesystem. /// The image encoder. - /// The library manager. /// The media encoder. public ImageProcessor( ILogger logger, IServerApplicationPaths appPaths, IFileSystem fileSystem, IImageEncoder imageEncoder, - Func libraryManager, Func mediaEncoder) { _logger = logger; _fileSystem = fileSystem; _imageEncoder = imageEncoder; - _libraryManager = libraryManager; _mediaEncoder = mediaEncoder; _appPaths = appPaths; } @@ -126,21 +122,9 @@ namespace Emby.Drawing throw new ArgumentNullException(nameof(options)); } - var libraryManager = _libraryManager(); - ItemImageInfo originalImage = options.Image; BaseItem item = options.Item; - if (!originalImage.IsLocalFile) - { - if (item == null) - { - item = libraryManager.GetItemById(options.ItemId); - } - - originalImage = await libraryManager.ConvertImageToLocal(item, originalImage, options.ImageIndex).ConfigureAwait(false); - } - string originalImagePath = originalImage.Path; DateTime dateModified = originalImage.DateModified; ImageDimensions? originalImageSize = null; @@ -312,10 +296,6 @@ namespace Emby.Drawing /// public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info) - => GetImageDimensions(item, info, true); - - /// - public ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem) { int width = info.Width; int height = info.Height; @@ -332,11 +312,6 @@ namespace Emby.Drawing info.Width = size.Width; info.Height = size.Height; - if (updateItem) - { - _libraryManager().UpdateImages(item); - } - return size; } diff --git a/Emby.Photos/PhotoProvider.cs b/Emby.Photos/PhotoProvider.cs index 63631e512b..987cb7fb2a 100644 --- a/Emby.Photos/PhotoProvider.cs +++ b/Emby.Photos/PhotoProvider.cs @@ -160,7 +160,7 @@ namespace Emby.Photos try { - var size = _imageProcessor.GetImageDimensions(item, img, false); + var size = _imageProcessor.GetImageDimensions(item, img); if (size.Width > 0 && size.Height > 0) { diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index c5b8878f84..a6ad005e0d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -723,7 +723,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => LibraryManager, () => MediaEncoder); + ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => MediaEncoder); serviceCollection.AddSingleton(ImageProcessor); serviceCollection.AddSingleton(); diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index af455987bc..c11e0c1b7e 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -332,7 +332,8 @@ namespace MediaBrowser.Api.Images var fileInfo = _fileSystem.GetFileInfo(info.Path); length = fileInfo.Length; - ImageDimensions size = _imageProcessor.GetImageDimensions(item, info, true); + ImageDimensions size = _imageProcessor.GetImageDimensions(item, info); + _libraryManager.UpdateImages(item); width = size.Width; height = size.Height; @@ -606,6 +607,12 @@ namespace MediaBrowser.Api.Images IDictionary headers, bool isHeadRequest) { + if (!image.IsLocalFile) + { + item ??= _libraryManager.GetItemById(itemId); + image = await _libraryManager.ConvertImageToLocal(item, image, request.Index ?? 0).ConfigureAwait(false); + } + var options = new ImageProcessingOptions { CropWhiteSpace = cropwhitespace, diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs index 79399807fd..36c746624e 100644 --- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs +++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs @@ -40,15 +40,6 @@ namespace MediaBrowser.Controller.Drawing /// ImageDimensions ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info); - /// - /// Gets the dimensions of the image. - /// - /// The base item. - /// The information. - /// Whether or not the item info should be updated. - /// ImageDimensions - ImageDimensions GetImageDimensions(BaseItem item, ItemImageInfo info, bool updateItem); - /// /// Gets the image cache tag. /// From 07cebbeae2bbbe63f0f97428e73e419220ab5804 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 17:12:24 -0400 Subject: [PATCH 081/517] Register and construct IImageProcessor, SqliteItemRepository and IImageEncoder correctly --- Emby.Drawing/ImageProcessor.cs | 8 ++--- .../ApplicationHost.cs | 33 ++++++++----------- .../Data/SqliteItemRepository.cs | 13 ++++---- .../Emby.Server.Implementations.csproj | 1 + Jellyfin.Drawing.Skia/SkiaEncoder.cs | 17 +++++++--- Jellyfin.Server/CoreAppHost.cs | 3 -- Jellyfin.Server/Program.cs | 20 ----------- 7 files changed, 38 insertions(+), 57 deletions(-) diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index a9cab147c8..903b958a4f 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -33,7 +33,7 @@ namespace Emby.Drawing private readonly IFileSystem _fileSystem; private readonly IServerApplicationPaths _appPaths; private readonly IImageEncoder _imageEncoder; - private readonly Func _mediaEncoder; + private readonly IMediaEncoder _mediaEncoder; private bool _disposed = false; @@ -50,7 +50,7 @@ namespace Emby.Drawing IServerApplicationPaths appPaths, IFileSystem fileSystem, IImageEncoder imageEncoder, - Func mediaEncoder) + IMediaEncoder mediaEncoder) { _logger = logger; _fileSystem = fileSystem; @@ -359,13 +359,13 @@ namespace Emby.Drawing { string filename = (originalImagePath + dateModified.Ticks.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("N", CultureInfo.InvariantCulture); - string cacheExtension = _mediaEncoder().SupportsEncoder("libwebp") ? ".webp" : ".png"; + string cacheExtension = _mediaEncoder.SupportsEncoder("libwebp") ? ".webp" : ".png"; var outputPath = Path.Combine(_appPaths.ImageCachePath, "converted-images", filename + cacheExtension); var file = _fileSystem.GetFileInfo(outputPath); if (!file.Exists) { - await _mediaEncoder().ConvertImage(originalImagePath, outputPath).ConfigureAwait(false); + await _mediaEncoder.ConvertImage(originalImagePath, outputPath).ConfigureAwait(false); dateModified = _fileSystem.GetLastWriteTimeUtc(outputPath); } else diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index a6ad005e0d..ff4fb54b55 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -48,6 +48,7 @@ using Emby.Server.Implementations.Session; using Emby.Server.Implementations.SocketSharp; using Emby.Server.Implementations.TV; using Emby.Server.Implementations.Updates; +using Jellyfin.Drawing.Skia; using MediaBrowser.Api; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; @@ -262,8 +263,6 @@ namespace Emby.Server.Implementations /// The directory watchers. private ILibraryMonitor LibraryMonitor { get; set; } - public IImageProcessor ImageProcessor { get; set; } - /// /// Gets or sets the media encoder. /// @@ -278,8 +277,6 @@ namespace Emby.Server.Implementations /// The user data repository. private IUserDataManager UserDataManager { get; set; } - internal SqliteItemRepository ItemRepository { get; set; } - private IAuthenticationRepository AuthenticationRepository { get; set; } /// @@ -290,8 +287,6 @@ namespace Emby.Server.Implementations public IStartupOptions StartupOptions { get; } - internal IImageEncoder ImageEncoder { get; private set; } - protected IProcessFactory ProcessFactory { get; private set; } protected readonly IXmlSerializer XmlSerializer; @@ -316,7 +311,6 @@ namespace Emby.Server.Implementations ILoggerFactory loggerFactory, IStartupOptions options, IFileSystem fileSystem, - IImageEncoder imageEncoder, INetworkManager networkManager) { XmlSerializer = new MyXmlSerializer(); @@ -334,8 +328,6 @@ namespace Emby.Server.Implementations StartupOptions = options; - ImageEncoder = imageEncoder; - fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); NetworkManager.NetworkChanged += OnNetworkChanged; @@ -603,6 +595,11 @@ namespace Emby.Server.Implementations /// protected async Task RegisterServices(IServiceCollection serviceCollection, IConfiguration startupConfig) { + var imageEncoderType = SkiaEncoder.IsNativeLibAvailable() + ? typeof(SkiaEncoder) + : typeof(NullImageEncoder); + serviceCollection.AddSingleton(typeof(IImageEncoder), imageEncoderType); + serviceCollection.AddMemoryCache(); serviceCollection.AddSingleton(ConfigurationManager); @@ -672,8 +669,7 @@ namespace Emby.Server.Implementations FileSystemManager); serviceCollection.AddSingleton(_displayPreferencesRepository); - ItemRepository = new SqliteItemRepository(ServerConfigurationManager, this, LoggerFactory.CreateLogger(), LocalizationManager); - serviceCollection.AddSingleton(ItemRepository); + serviceCollection.AddSingleton(); AuthenticationRepository = GetAuthenticationRepository(); serviceCollection.AddSingleton(AuthenticationRepository); @@ -685,7 +681,7 @@ namespace Emby.Server.Implementations _userRepository, XmlSerializer, NetworkManager, - () => ImageProcessor, + Resolve, Resolve, this, JsonSerializer, @@ -723,8 +719,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - ImageProcessor = new ImageProcessor(LoggerFactory.CreateLogger(), ServerConfigurationManager.ApplicationPaths, FileSystemManager, ImageEncoder, () => MediaEncoder); - serviceCollection.AddSingleton(ImageProcessor); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -797,8 +792,10 @@ namespace Emby.Server.Implementations ((UserManager)UserManager).Initialize(); ((UserDataManager)UserDataManager).Repository = userDataRepo; - ItemRepository.Initialize(userDataRepo, UserManager); - ((LibraryManager)LibraryManager).ItemRepository = ItemRepository; + + var itemRepo = (SqliteItemRepository)Resolve(); + itemRepo.Initialize(userDataRepo, UserManager); + ((LibraryManager)LibraryManager).ItemRepository = itemRepo; FindParts(); } @@ -898,15 +895,13 @@ namespace Emby.Server.Implementations /// private void SetStaticProperties() { - ItemRepository.ImageProcessor = ImageProcessor; - // For now there's no real way to inject these properly BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem"); BaseItem.ConfigurationManager = ServerConfigurationManager; BaseItem.LibraryManager = LibraryManager; BaseItem.ProviderManager = Resolve(); BaseItem.LocalizationManager = LocalizationManager; - BaseItem.ItemRepository = ItemRepository; + BaseItem.ItemRepository = Resolve(); User.UserManager = UserManager; BaseItem.FileSystem = FileSystemManager; BaseItem.UserDataManager = UserDataManager; diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index e3242f7b4f..227f1a5e7e 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -39,12 +39,11 @@ namespace Emby.Server.Implementations.Data { private const string ChaptersTableName = "Chapters2"; - /// - /// The _app paths - /// private readonly IServerConfigurationManager _config; private readonly IServerApplicationHost _appHost; private readonly ILocalizationManager _localization; + // TODO: Remove this dependency + private readonly IImageProcessor _imageProcessor; private readonly TypeMapper _typeMapper; private readonly JsonSerializerOptions _jsonOptions; @@ -71,7 +70,8 @@ namespace Emby.Server.Implementations.Data IServerConfigurationManager config, IServerApplicationHost appHost, ILogger logger, - ILocalizationManager localization) + ILocalizationManager localization, + IImageProcessor imageProcessor) : base(logger) { if (config == null) @@ -82,6 +82,7 @@ namespace Emby.Server.Implementations.Data _config = config; _appHost = appHost; _localization = localization; + _imageProcessor = imageProcessor; _typeMapper = new TypeMapper(); _jsonOptions = JsonDefaults.GetOptions(); @@ -98,8 +99,6 @@ namespace Emby.Server.Implementations.Data /// protected override TempStoreMode TempStore => TempStoreMode.Memory; - public IImageProcessor ImageProcessor { get; set; } - /// /// Opens the connection to the database /// @@ -1991,7 +1990,7 @@ namespace Emby.Server.Implementations.Data if (!string.IsNullOrEmpty(chapter.ImagePath)) { - chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter); + chapter.ImageTag = _imageProcessor.GetImageCacheTag(item, chapter); } } diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index d302d89843..6c20842c7f 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -4,6 +4,7 @@ + diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index a67118f188..97717e6263 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -78,12 +78,21 @@ namespace Jellyfin.Drawing.Skia => new HashSet() { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png }; /// - /// Test to determine if the native lib is available. + /// Check if the native lib is available. /// - public static void TestSkia() + /// True if the native lib is available, otherwise false. + public static bool IsNativeLibAvailable() { - // test an operation that requires the native library - SKPMColor.PreMultiply(SKColors.Black); + try + { + // test an operation that requires the native library + SKPMColor.PreMultiply(SKColors.Black); + return true; + } + catch (Exception) + { + return false; + } } private static bool IsTransparent(SKColor color) diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index 1d5313c13e..b35200e757 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -20,21 +20,18 @@ namespace Jellyfin.Server /// The to be used by the . /// The to be used by the . /// The to be used by the . - /// The to be used by the . /// The to be used by the . public CoreAppHost( ServerApplicationPaths applicationPaths, ILoggerFactory loggerFactory, StartupOptions options, IFileSystem fileSystem, - IImageEncoder imageEncoder, INetworkManager networkManager) : base( applicationPaths, loggerFactory, options, fileSystem, - imageEncoder, networkManager) { } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 6be9ba4f2d..5e9c15e20e 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -183,7 +183,6 @@ namespace Jellyfin.Server _loggerFactory, options, new ManagedFileSystem(_loggerFactory.CreateLogger(), appPaths), - GetImageEncoder(appPaths), new NetworkManager(_loggerFactory.CreateLogger())); try @@ -553,25 +552,6 @@ namespace Jellyfin.Server } } - private static IImageEncoder GetImageEncoder(IApplicationPaths appPaths) - { - try - { - // Test if the native lib is available - SkiaEncoder.TestSkia(); - - return new SkiaEncoder( - _loggerFactory.CreateLogger(), - appPaths); - } - catch (Exception ex) - { - _logger.LogWarning(ex, $"Skia not available. Will fallback to {nameof(NullImageEncoder)}."); - } - - return new NullImageEncoder(); - } - private static void StartNewInstance(StartupOptions options) { _logger.LogInformation("Starting new instance"); From d173358065c65710476b225168bd8a348d99cf11 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 17:19:16 -0400 Subject: [PATCH 082/517] Move ApplicationHost certificate initialization to constructor --- .../ApplicationHost.cs | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ff4fb54b55..57ec71c9da 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -331,6 +331,13 @@ namespace Emby.Server.Implementations fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); NetworkManager.NetworkChanged += OnNetworkChanged; + + CertificateInfo = new CertificateInfo + { + Path = ServerConfigurationManager.Configuration.CertificatePath, + Password = ServerConfigurationManager.Configuration.CertificatePassword + }; + Certificate = GetCertificate(CertificateInfo); } public string ExpandVirtualPath(string path) @@ -712,9 +719,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(new SearchEngine(LoggerFactory, LibraryManager, UserManager)); - CertificateInfo = GetCertificateInfo(true); - Certificate = GetCertificate(CertificateInfo); - serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -1106,16 +1110,6 @@ namespace Emby.Server.Implementations }); } - private CertificateInfo GetCertificateInfo(bool generateCertificate) - { - // Custom cert - return new CertificateInfo - { - Path = ServerConfigurationManager.Configuration.CertificatePath, - Password = ServerConfigurationManager.Configuration.CertificatePassword - }; - } - /// /// Called when [configuration updated]. /// @@ -1148,8 +1142,7 @@ namespace Emby.Server.Implementations } var currentCertPath = CertificateInfo?.Path; - var newCertInfo = GetCertificateInfo(false); - var newCertPath = newCertInfo?.Path; + var newCertPath = ServerConfigurationManager.Configuration.CertificatePath; if (!string.Equals(currentCertPath, newCertPath, StringComparison.OrdinalIgnoreCase)) { From c2b21ce5531a2b53fd0d0cc8231b4fd7d4261abe Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 17:33:00 -0400 Subject: [PATCH 083/517] Register and construct ILibraryMonitor correctly --- .../ApplicationHost.cs | 11 +--- .../IO/LibraryMonitor.cs | 58 +++++++++---------- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 57ec71c9da..51c6f13424 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -257,12 +257,6 @@ namespace Emby.Server.Implementations /// The library manager. internal ILibraryManager LibraryManager { get; set; } - /// - /// Gets or sets the directory watchers. - /// - /// The directory watchers. - private ILibraryMonitor LibraryMonitor { get; set; } - /// /// Gets or sets the media encoder. /// @@ -708,14 +702,13 @@ namespace Emby.Server.Implementations StartupOptions.FFmpegPath); serviceCollection.AddSingleton(MediaEncoder); - LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, Resolve, Resolve, MediaEncoder); + LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, Resolve, FileSystemManager, Resolve, Resolve, MediaEncoder); serviceCollection.AddSingleton(LibraryManager); var musicManager = new MusicManager(LibraryManager); serviceCollection.AddSingleton(musicManager); - LibraryMonitor = new LibraryMonitor(LoggerFactory, LibraryManager, ServerConfigurationManager, FileSystemManager); - serviceCollection.AddSingleton(LibraryMonitor); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(new SearchEngine(LoggerFactory, LibraryManager, UserManager)); diff --git a/Emby.Server.Implementations/IO/LibraryMonitor.cs b/Emby.Server.Implementations/IO/LibraryMonitor.cs index b1fb8cc635..5a1eb43bcb 100644 --- a/Emby.Server.Implementations/IO/LibraryMonitor.cs +++ b/Emby.Server.Implementations/IO/LibraryMonitor.cs @@ -17,6 +17,11 @@ namespace Emby.Server.Implementations.IO { public class LibraryMonitor : ILibraryMonitor { + private readonly ILogger _logger; + private readonly ILibraryManager _libraryManager; + private readonly IServerConfigurationManager _configurationManager; + private readonly IFileSystem _fileSystem; + /// /// The file system watchers. /// @@ -113,34 +118,23 @@ namespace Emby.Server.Implementations.IO } catch (Exception ex) { - Logger.LogError(ex, "Error in ReportFileSystemChanged for {path}", path); + _logger.LogError(ex, "Error in ReportFileSystemChanged for {path}", path); } } } - /// - /// Gets or sets the logger. - /// - /// The logger. - private ILogger Logger { get; set; } - - private ILibraryManager LibraryManager { get; set; } - private IServerConfigurationManager ConfigurationManager { get; set; } - - private readonly IFileSystem _fileSystem; - /// /// Initializes a new instance of the class. /// public LibraryMonitor( - ILoggerFactory loggerFactory, + ILogger logger, ILibraryManager libraryManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem) { - LibraryManager = libraryManager; - Logger = loggerFactory.CreateLogger(GetType().Name); - ConfigurationManager = configurationManager; + _libraryManager = libraryManager; + _logger = logger; + _configurationManager = configurationManager; _fileSystem = fileSystem; } @@ -151,7 +145,7 @@ namespace Emby.Server.Implementations.IO return false; } - var options = LibraryManager.GetLibraryOptions(item); + var options = _libraryManager.GetLibraryOptions(item); if (options != null) { @@ -163,12 +157,12 @@ namespace Emby.Server.Implementations.IO public void Start() { - LibraryManager.ItemAdded += OnLibraryManagerItemAdded; - LibraryManager.ItemRemoved += OnLibraryManagerItemRemoved; + _libraryManager.ItemAdded += OnLibraryManagerItemAdded; + _libraryManager.ItemRemoved += OnLibraryManagerItemRemoved; var pathsToWatch = new List(); - var paths = LibraryManager + var paths = _libraryManager .RootFolder .Children .Where(IsLibraryMonitorEnabled) @@ -261,7 +255,7 @@ namespace Emby.Server.Implementations.IO if (!Directory.Exists(path)) { // Seeing a crash in the mono runtime due to an exception being thrown on a different thread - Logger.LogInformation("Skipping realtime monitor for {Path} because the path does not exist", path); + _logger.LogInformation("Skipping realtime monitor for {Path} because the path does not exist", path); return; } @@ -297,7 +291,7 @@ namespace Emby.Server.Implementations.IO if (_fileSystemWatchers.TryAdd(path, newWatcher)) { newWatcher.EnableRaisingEvents = true; - Logger.LogInformation("Watching directory " + path); + _logger.LogInformation("Watching directory " + path); } else { @@ -307,7 +301,7 @@ namespace Emby.Server.Implementations.IO } catch (Exception ex) { - Logger.LogError(ex, "Error watching path: {path}", path); + _logger.LogError(ex, "Error watching path: {path}", path); } }); } @@ -333,7 +327,7 @@ namespace Emby.Server.Implementations.IO { using (watcher) { - Logger.LogInformation("Stopping directory watching for path {Path}", watcher.Path); + _logger.LogInformation("Stopping directory watching for path {Path}", watcher.Path); watcher.Created -= OnWatcherChanged; watcher.Deleted -= OnWatcherChanged; @@ -372,7 +366,7 @@ namespace Emby.Server.Implementations.IO var ex = e.GetException(); var dw = (FileSystemWatcher)sender; - Logger.LogError(ex, "Error in Directory watcher for: {Path}", dw.Path); + _logger.LogError(ex, "Error in Directory watcher for: {Path}", dw.Path); DisposeWatcher(dw, true); } @@ -390,7 +384,7 @@ namespace Emby.Server.Implementations.IO } catch (Exception ex) { - Logger.LogError(ex, "Exception in ReportFileSystemChanged. Path: {FullPath}", e.FullPath); + _logger.LogError(ex, "Exception in ReportFileSystemChanged. Path: {FullPath}", e.FullPath); } } @@ -416,13 +410,13 @@ namespace Emby.Server.Implementations.IO { if (_fileSystem.AreEqual(i, path)) { - Logger.LogDebug("Ignoring change to {Path}", path); + _logger.LogDebug("Ignoring change to {Path}", path); return true; } if (_fileSystem.ContainsSubPath(i, path)) { - Logger.LogDebug("Ignoring change to {Path}", path); + _logger.LogDebug("Ignoring change to {Path}", path); return true; } @@ -430,7 +424,7 @@ namespace Emby.Server.Implementations.IO var parent = Path.GetDirectoryName(i); if (!string.IsNullOrEmpty(parent) && _fileSystem.AreEqual(parent, path)) { - Logger.LogDebug("Ignoring change to {Path}", path); + _logger.LogDebug("Ignoring change to {Path}", path); return true; } @@ -485,7 +479,7 @@ namespace Emby.Server.Implementations.IO } } - var newRefresher = new FileRefresher(path, ConfigurationManager, LibraryManager, Logger); + var newRefresher = new FileRefresher(path, _configurationManager, _libraryManager, _logger); newRefresher.Completed += NewRefresher_Completed; _activeRefreshers.Add(newRefresher); } @@ -502,8 +496,8 @@ namespace Emby.Server.Implementations.IO /// public void Stop() { - LibraryManager.ItemAdded -= OnLibraryManagerItemAdded; - LibraryManager.ItemRemoved -= OnLibraryManagerItemRemoved; + _libraryManager.ItemAdded -= OnLibraryManagerItemAdded; + _libraryManager.ItemRemoved -= OnLibraryManagerItemRemoved; foreach (var watcher in _fileSystemWatchers.Values.ToList()) { From 7fd25f94f3432f1c9319e49f4d62454f45ad7515 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 18:22:29 -0400 Subject: [PATCH 084/517] Inject and construct ISearchEngine and IMusicManager correctly --- Emby.Server.Implementations/ApplicationHost.cs | 5 ++--- Emby.Server.Implementations/Library/SearchEngine.cs | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 51c6f13424..ba149590fb 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -705,12 +705,11 @@ namespace Emby.Server.Implementations LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, Resolve, FileSystemManager, Resolve, Resolve, MediaEncoder); serviceCollection.AddSingleton(LibraryManager); - var musicManager = new MusicManager(LibraryManager); - serviceCollection.AddSingleton(musicManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(new SearchEngine(LoggerFactory, LibraryManager, UserManager)); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs index 11d6c737ac..59a77607d2 100644 --- a/Emby.Server.Implementations/Library/SearchEngine.cs +++ b/Emby.Server.Implementations/Library/SearchEngine.cs @@ -17,16 +17,15 @@ namespace Emby.Server.Implementations.Library { public class SearchEngine : ISearchEngine { + private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; private readonly IUserManager _userManager; - private readonly ILogger _logger; - public SearchEngine(ILoggerFactory loggerFactory, ILibraryManager libraryManager, IUserManager userManager) + public SearchEngine(ILogger logger, ILibraryManager libraryManager, IUserManager userManager) { + _logger = logger; _libraryManager = libraryManager; _userManager = userManager; - - _logger = loggerFactory.CreateLogger("SearchEngine"); } public QueryResult GetSearchHints(SearchQuery query) From fe9f4e06d1362eb6d0e7cc5e68d8819b872cb7bc Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 18:28:46 -0400 Subject: [PATCH 085/517] Register and construct LibraryManager correctly --- .../ApplicationHost.cs | 21 +- .../Library/LibraryManager.cs | 227 ++++++++---------- 2 files changed, 107 insertions(+), 141 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ba149590fb..aca1abf9fd 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -251,12 +251,6 @@ namespace Emby.Server.Implementations /// The user manager. public IUserManager UserManager { get; set; } - /// - /// Gets or sets the library manager. - /// - /// The library manager. - internal ILibraryManager LibraryManager { get; set; } - /// /// Gets or sets the media encoder. /// @@ -702,8 +696,11 @@ namespace Emby.Server.Implementations StartupOptions.FFmpegPath); serviceCollection.AddSingleton(MediaEncoder); - LibraryManager = new LibraryManager(this, LoggerFactory, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, Resolve, FileSystemManager, Resolve, Resolve, MediaEncoder); - serviceCollection.AddSingleton(LibraryManager); + // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required + serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); + serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); + serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -789,9 +786,7 @@ namespace Emby.Server.Implementations ((UserDataManager)UserDataManager).Repository = userDataRepo; - var itemRepo = (SqliteItemRepository)Resolve(); - itemRepo.Initialize(userDataRepo, UserManager); - ((LibraryManager)LibraryManager).ItemRepository = itemRepo; + ((SqliteItemRepository)Resolve()).Initialize(userDataRepo, UserManager); FindParts(); } @@ -894,7 +889,7 @@ namespace Emby.Server.Implementations // For now there's no real way to inject these properly BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem"); BaseItem.ConfigurationManager = ServerConfigurationManager; - BaseItem.LibraryManager = LibraryManager; + BaseItem.LibraryManager = Resolve(); BaseItem.ProviderManager = Resolve(); BaseItem.LocalizationManager = LocalizationManager; BaseItem.ItemRepository = Resolve(); @@ -970,7 +965,7 @@ namespace Emby.Server.Implementations _httpServer.Init(GetExportTypes(), GetExports(), GetUrlPrefixes()); - LibraryManager.AddParts( + Resolve().AddParts( GetExports(), GetExports(), GetExports(), diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 8ec4d08be5..e2985c26cb 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -54,9 +54,29 @@ namespace Emby.Server.Implementations.Library /// public class LibraryManager : ILibraryManager { + private readonly ILogger _logger; + private readonly ITaskManager _taskManager; + private readonly IUserManager _userManager; + private readonly IUserDataManager _userDataRepository; + private readonly IServerConfigurationManager _configurationManager; + private readonly Lazy _libraryMonitorFactory; + private readonly Lazy _providerManagerFactory; + private readonly Lazy _userviewManagerFactory; + private readonly IServerApplicationHost _appHost; + private readonly IMediaEncoder _mediaEncoder; + private readonly IFileSystem _fileSystem; + private readonly IItemRepository _itemRepository; + private readonly ConcurrentDictionary _libraryItemsCache; + private NamingOptions _namingOptions; private string[] _videoFileExtensions; + private ILibraryMonitor LibraryMonitor => _libraryMonitorFactory.Value; + + private IProviderManager ProviderManager => _providerManagerFactory.Value; + + private IUserViewManager UserViewManager => _userviewManagerFactory.Value; + /// /// Gets or sets the postscan tasks. /// @@ -89,12 +109,6 @@ namespace Emby.Server.Implementations.Library /// The comparers. private IBaseItemComparer[] Comparers { get; set; } - /// - /// Gets or sets the active item repository - /// - /// The item repository. - public IItemRepository ItemRepository { get; set; } - /// /// Occurs when [item added]. /// @@ -110,90 +124,47 @@ namespace Emby.Server.Implementations.Library /// public event EventHandler ItemRemoved; - /// - /// The _logger - /// - private readonly ILogger _logger; - - /// - /// The _task manager - /// - private readonly ITaskManager _taskManager; - - /// - /// The _user manager - /// - private readonly IUserManager _userManager; - - /// - /// The _user data repository - /// - private readonly IUserDataManager _userDataRepository; - - /// - /// Gets or sets the configuration manager. - /// - /// The configuration manager. - private IServerConfigurationManager ConfigurationManager { get; set; } - - private readonly Func _libraryMonitorFactory; - private readonly Func _providerManagerFactory; - private readonly Func _userviewManager; public bool IsScanRunning { get; private set; } - private IServerApplicationHost _appHost; - private readonly IMediaEncoder _mediaEncoder; - - /// - /// The _library items cache - /// - private readonly ConcurrentDictionary _libraryItemsCache; - - /// - /// Gets the library items cache. - /// - /// The library items cache. - private ConcurrentDictionary LibraryItemsCache => _libraryItemsCache; - - private readonly IFileSystem _fileSystem; - /// /// Initializes a new instance of the class. /// /// The application host - /// The logger factory. + /// The logger. /// The task manager. /// The user manager. /// The configuration manager. /// The user data repository. public LibraryManager( IServerApplicationHost appHost, - ILoggerFactory loggerFactory, + ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, - Func libraryMonitorFactory, + Lazy libraryMonitorFactory, IFileSystem fileSystem, - Func providerManagerFactory, - Func userviewManager, - IMediaEncoder mediaEncoder) + Lazy providerManagerFactory, + Lazy userviewManagerFactory, + IMediaEncoder mediaEncoder, + IItemRepository itemRepository) { _appHost = appHost; - _logger = loggerFactory.CreateLogger(nameof(LibraryManager)); + _logger = logger; _taskManager = taskManager; _userManager = userManager; - ConfigurationManager = configurationManager; + _configurationManager = configurationManager; _userDataRepository = userDataRepository; _libraryMonitorFactory = libraryMonitorFactory; _fileSystem = fileSystem; _providerManagerFactory = providerManagerFactory; - _userviewManager = userviewManager; + _userviewManagerFactory = userviewManagerFactory; _mediaEncoder = mediaEncoder; + _itemRepository = itemRepository; _libraryItemsCache = new ConcurrentDictionary(); - ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated; + _configurationManager.ConfigurationUpdated += ConfigurationUpdated; RecordConfigurationValues(configurationManager.Configuration); } @@ -272,7 +243,7 @@ namespace Emby.Server.Implementations.Library /// The instance containing the event data. private void ConfigurationUpdated(object sender, EventArgs e) { - var config = ConfigurationManager.Configuration; + var config = _configurationManager.Configuration; var wizardChanged = config.IsStartupWizardCompleted != _wizardCompleted; @@ -306,7 +277,7 @@ namespace Emby.Server.Implementations.Library } } - LibraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; }); + _libraryItemsCache.AddOrUpdate(item.Id, item, delegate { return item; }); } public void DeleteItem(BaseItem item, DeleteOptions options) @@ -437,10 +408,10 @@ namespace Emby.Server.Implementations.Library item.SetParent(null); - ItemRepository.DeleteItem(item.Id, CancellationToken.None); + _itemRepository.DeleteItem(item.Id, CancellationToken.None); foreach (var child in children) { - ItemRepository.DeleteItem(child.Id, CancellationToken.None); + _itemRepository.DeleteItem(child.Id, CancellationToken.None); } _libraryItemsCache.TryRemove(item.Id, out BaseItem removed); @@ -509,15 +480,15 @@ namespace Emby.Server.Implementations.Library throw new ArgumentNullException(nameof(type)); } - if (key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath, StringComparison.Ordinal)) + if (key.StartsWith(_configurationManager.ApplicationPaths.ProgramDataPath, StringComparison.Ordinal)) { // Try to normalize paths located underneath program-data in an attempt to make them more portable - key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length) + key = key.Substring(_configurationManager.ApplicationPaths.ProgramDataPath.Length) .TrimStart(new[] { '/', '\\' }) .Replace("/", "\\"); } - if (forceCaseInsensitive || !ConfigurationManager.Configuration.EnableCaseSensitiveItemIds) + if (forceCaseInsensitive || !_configurationManager.Configuration.EnableCaseSensitiveItemIds) { key = key.ToLowerInvariant(); } @@ -550,7 +521,7 @@ namespace Emby.Server.Implementations.Library collectionType = GetContentTypeOverride(fullPath, true); } - var args = new ItemResolveArgs(ConfigurationManager.ApplicationPaths, directoryService) + var args = new ItemResolveArgs(_configurationManager.ApplicationPaths, directoryService) { Parent = parent, Path = fullPath, @@ -720,7 +691,7 @@ namespace Emby.Server.Implementations.Library /// Cannot create the root folder until plugins have loaded. public AggregateFolder CreateRootFolder() { - var rootFolderPath = ConfigurationManager.ApplicationPaths.RootFolderPath; + var rootFolderPath = _configurationManager.ApplicationPaths.RootFolderPath; Directory.CreateDirectory(rootFolderPath); @@ -734,7 +705,7 @@ namespace Emby.Server.Implementations.Library } // Add in the plug-in folders - var path = Path.Combine(ConfigurationManager.ApplicationPaths.DataPath, "playlists"); + var path = Path.Combine(_configurationManager.ApplicationPaths.DataPath, "playlists"); Directory.CreateDirectory(path); @@ -786,7 +757,7 @@ namespace Emby.Server.Implementations.Library { if (_userRootFolder == null) { - var userRootPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath; + var userRootPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; _logger.LogDebug("Creating userRootPath at {path}", userRootPath); Directory.CreateDirectory(userRootPath); @@ -980,7 +951,7 @@ namespace Emby.Server.Implementations.Library where T : BaseItem, new() { var path = getPathFn(name); - var forceCaseInsensitiveId = ConfigurationManager.Configuration.EnableNormalizedItemByNameIds; + var forceCaseInsensitiveId = _configurationManager.Configuration.EnableNormalizedItemByNameIds; return GetNewItemIdInternal(path, typeof(T), forceCaseInsensitiveId); } @@ -994,7 +965,7 @@ namespace Emby.Server.Implementations.Library public Task ValidatePeople(CancellationToken cancellationToken, IProgress progress) { // Ensure the location is available. - Directory.CreateDirectory(ConfigurationManager.ApplicationPaths.PeoplePath); + Directory.CreateDirectory(_configurationManager.ApplicationPaths.PeoplePath); return new PeopleValidator(this, _logger, _fileSystem).ValidatePeople(cancellationToken, progress); } @@ -1031,7 +1002,7 @@ namespace Emby.Server.Implementations.Library public async Task ValidateMediaLibraryInternal(IProgress progress, CancellationToken cancellationToken) { IsScanRunning = true; - _libraryMonitorFactory().Stop(); + LibraryMonitor.Stop(); try { @@ -1039,7 +1010,7 @@ namespace Emby.Server.Implementations.Library } finally { - _libraryMonitorFactory().Start(); + LibraryMonitor.Start(); IsScanRunning = false; } } @@ -1148,7 +1119,7 @@ namespace Emby.Server.Implementations.Library progress.Report(percent * 100); } - ItemRepository.UpdateInheritedValues(cancellationToken); + _itemRepository.UpdateInheritedValues(cancellationToken); progress.Report(100); } @@ -1168,9 +1139,9 @@ namespace Emby.Server.Implementations.Library var topLibraryFolders = GetUserRootFolder().Children.ToList(); _logger.LogDebug("Getting refreshQueue"); - var refreshQueue = includeRefreshState ? _providerManagerFactory().GetRefreshQueue() : null; + var refreshQueue = includeRefreshState ? ProviderManager.GetRefreshQueue() : null; - return _fileSystem.GetDirectoryPaths(ConfigurationManager.ApplicationPaths.DefaultUserViewsPath) + return _fileSystem.GetDirectoryPaths(_configurationManager.ApplicationPaths.DefaultUserViewsPath) .Select(dir => GetVirtualFolderInfo(dir, topLibraryFolders, refreshQueue)) .ToList(); } @@ -1245,7 +1216,7 @@ namespace Emby.Server.Implementations.Library throw new ArgumentException("Guid can't be empty", nameof(id)); } - if (LibraryItemsCache.TryGetValue(id, out BaseItem item)) + if (_libraryItemsCache.TryGetValue(id, out BaseItem item)) { return item; } @@ -1276,7 +1247,7 @@ namespace Emby.Server.Implementations.Library AddUserToQuery(query, query.User, allowExternalContent); } - return ItemRepository.GetItemList(query); + return _itemRepository.GetItemList(query); } public List GetItemList(InternalItemsQuery query) @@ -1300,7 +1271,7 @@ namespace Emby.Server.Implementations.Library AddUserToQuery(query, query.User); } - return ItemRepository.GetCount(query); + return _itemRepository.GetCount(query); } public List GetItemList(InternalItemsQuery query, List parents) @@ -1315,7 +1286,7 @@ namespace Emby.Server.Implementations.Library } } - return ItemRepository.GetItemList(query); + return _itemRepository.GetItemList(query); } public QueryResult QueryItems(InternalItemsQuery query) @@ -1327,12 +1298,12 @@ namespace Emby.Server.Implementations.Library if (query.EnableTotalRecordCount) { - return ItemRepository.GetItems(query); + return _itemRepository.GetItems(query); } return new QueryResult { - Items = ItemRepository.GetItemList(query).ToArray() + Items = _itemRepository.GetItemList(query).ToArray() }; } @@ -1343,7 +1314,7 @@ namespace Emby.Server.Implementations.Library AddUserToQuery(query, query.User); } - return ItemRepository.GetItemIdsList(query); + return _itemRepository.GetItemIdsList(query); } public QueryResult<(BaseItem, ItemCounts)> GetStudios(InternalItemsQuery query) @@ -1354,7 +1325,7 @@ namespace Emby.Server.Implementations.Library } SetTopParentOrAncestorIds(query); - return ItemRepository.GetStudios(query); + return _itemRepository.GetStudios(query); } public QueryResult<(BaseItem, ItemCounts)> GetGenres(InternalItemsQuery query) @@ -1365,7 +1336,7 @@ namespace Emby.Server.Implementations.Library } SetTopParentOrAncestorIds(query); - return ItemRepository.GetGenres(query); + return _itemRepository.GetGenres(query); } public QueryResult<(BaseItem, ItemCounts)> GetMusicGenres(InternalItemsQuery query) @@ -1376,7 +1347,7 @@ namespace Emby.Server.Implementations.Library } SetTopParentOrAncestorIds(query); - return ItemRepository.GetMusicGenres(query); + return _itemRepository.GetMusicGenres(query); } public QueryResult<(BaseItem, ItemCounts)> GetAllArtists(InternalItemsQuery query) @@ -1387,7 +1358,7 @@ namespace Emby.Server.Implementations.Library } SetTopParentOrAncestorIds(query); - return ItemRepository.GetAllArtists(query); + return _itemRepository.GetAllArtists(query); } public QueryResult<(BaseItem, ItemCounts)> GetArtists(InternalItemsQuery query) @@ -1398,7 +1369,7 @@ namespace Emby.Server.Implementations.Library } SetTopParentOrAncestorIds(query); - return ItemRepository.GetArtists(query); + return _itemRepository.GetArtists(query); } private void SetTopParentOrAncestorIds(InternalItemsQuery query) @@ -1439,7 +1410,7 @@ namespace Emby.Server.Implementations.Library } SetTopParentOrAncestorIds(query); - return ItemRepository.GetAlbumArtists(query); + return _itemRepository.GetAlbumArtists(query); } public QueryResult GetItemsResult(InternalItemsQuery query) @@ -1460,10 +1431,10 @@ namespace Emby.Server.Implementations.Library if (query.EnableTotalRecordCount) { - return ItemRepository.GetItems(query); + return _itemRepository.GetItems(query); } - var list = ItemRepository.GetItemList(query); + var list = _itemRepository.GetItemList(query); return new QueryResult { @@ -1509,7 +1480,7 @@ namespace Emby.Server.Implementations.Library string.IsNullOrEmpty(query.SeriesPresentationUniqueKey) && query.ItemIds.Length == 0) { - var userViews = _userviewManager().GetUserViews(new UserViewQuery + var userViews = UserViewManager.GetUserViews(new UserViewQuery { UserId = user.Id, IncludeHidden = true, @@ -1809,7 +1780,7 @@ namespace Emby.Server.Implementations.Library // Don't iterate multiple times var itemsList = items.ToList(); - ItemRepository.SaveItems(itemsList, cancellationToken); + _itemRepository.SaveItems(itemsList, cancellationToken); foreach (var item in itemsList) { @@ -1846,7 +1817,7 @@ namespace Emby.Server.Implementations.Library public void UpdateImages(BaseItem item) { - ItemRepository.SaveImages(item); + _itemRepository.SaveImages(item); RegisterItem(item); } @@ -1863,7 +1834,7 @@ namespace Emby.Server.Implementations.Library { if (item.IsFileProtocol) { - _providerManagerFactory().SaveMetadata(item, updateReason); + ProviderManager.SaveMetadata(item, updateReason); } item.DateLastSaved = DateTime.UtcNow; @@ -1871,7 +1842,7 @@ namespace Emby.Server.Implementations.Library RegisterItem(item); } - ItemRepository.SaveItems(itemsList, cancellationToken); + _itemRepository.SaveItems(itemsList, cancellationToken); if (ItemUpdated != null) { @@ -1947,7 +1918,7 @@ namespace Emby.Server.Implementations.Library /// BaseItem. public BaseItem RetrieveItem(Guid id) { - return ItemRepository.RetrieveItem(id); + return _itemRepository.RetrieveItem(id); } public List GetCollectionFolders(BaseItem item) @@ -2066,7 +2037,7 @@ namespace Emby.Server.Implementations.Library private string GetContentTypeOverride(string path, bool inherit) { - var nameValuePair = ConfigurationManager.Configuration.ContentTypes + var nameValuePair = _configurationManager.Configuration.ContentTypes .FirstOrDefault(i => _fileSystem.AreEqual(i.Name, path) || (inherit && !string.IsNullOrEmpty(i.Name) && _fileSystem.ContainsSubPath(i.Name, path))); @@ -2115,7 +2086,7 @@ namespace Emby.Server.Implementations.Library string sortName) { var path = Path.Combine( - ConfigurationManager.ApplicationPaths.InternalMetadataPath, + _configurationManager.ApplicationPaths.InternalMetadataPath, "views", _fileSystem.GetValidFilename(viewType)); @@ -2147,7 +2118,7 @@ namespace Emby.Server.Implementations.Library if (refresh) { item.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None); - _providerManagerFactory().QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal); + ProviderManager.QueueRefresh(item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)), RefreshPriority.Normal); } return item; @@ -2165,7 +2136,7 @@ namespace Emby.Server.Implementations.Library var id = GetNewItemId(idValues, typeof(UserView)); - var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture)); + var path = Path.Combine(_configurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture)); var item = GetItemById(id) as UserView; @@ -2202,7 +2173,7 @@ namespace Emby.Server.Implementations.Library if (refresh) { - _providerManagerFactory().QueueRefresh( + ProviderManager.QueueRefresh( item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { @@ -2269,7 +2240,7 @@ namespace Emby.Server.Implementations.Library if (refresh) { - _providerManagerFactory().QueueRefresh( + ProviderManager.QueueRefresh( item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { @@ -2303,7 +2274,7 @@ namespace Emby.Server.Implementations.Library var id = GetNewItemId(idValues, typeof(UserView)); - var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture)); + var path = Path.Combine(_configurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture)); var item = GetItemById(id) as UserView; @@ -2346,7 +2317,7 @@ namespace Emby.Server.Implementations.Library if (refresh) { - _providerManagerFactory().QueueRefresh( + ProviderManager.QueueRefresh( item.Id, new MetadataRefreshOptions(new DirectoryService(_fileSystem)) { @@ -2677,8 +2648,8 @@ namespace Emby.Server.Implementations.Library } } - var metadataPath = ConfigurationManager.Configuration.MetadataPath; - var metadataNetworkPath = ConfigurationManager.Configuration.MetadataNetworkPath; + var metadataPath = _configurationManager.Configuration.MetadataPath; + var metadataNetworkPath = _configurationManager.Configuration.MetadataNetworkPath; if (!string.IsNullOrWhiteSpace(metadataPath) && !string.IsNullOrWhiteSpace(metadataNetworkPath)) { @@ -2689,7 +2660,7 @@ namespace Emby.Server.Implementations.Library } } - foreach (var map in ConfigurationManager.Configuration.PathSubstitutions) + foreach (var map in _configurationManager.Configuration.PathSubstitutions) { if (!string.IsNullOrWhiteSpace(map.From)) { @@ -2758,7 +2729,7 @@ namespace Emby.Server.Implementations.Library public List GetPeople(InternalPeopleQuery query) { - return ItemRepository.GetPeople(query); + return _itemRepository.GetPeople(query); } public List GetPeople(BaseItem item) @@ -2781,7 +2752,7 @@ namespace Emby.Server.Implementations.Library public List GetPeopleItems(InternalPeopleQuery query) { - return ItemRepository.GetPeopleNames(query).Select(i => + return _itemRepository.GetPeopleNames(query).Select(i => { try { @@ -2798,7 +2769,7 @@ namespace Emby.Server.Implementations.Library public List GetPeopleNames(InternalPeopleQuery query) { - return ItemRepository.GetPeopleNames(query); + return _itemRepository.GetPeopleNames(query); } public void UpdatePeople(BaseItem item, List people) @@ -2808,7 +2779,7 @@ namespace Emby.Server.Implementations.Library return; } - ItemRepository.UpdatePeople(item.Id, people); + _itemRepository.UpdatePeople(item.Id, people); } public async Task ConvertImageToLocal(BaseItem item, ItemImageInfo image, int imageIndex) @@ -2819,7 +2790,7 @@ namespace Emby.Server.Implementations.Library { _logger.LogDebug("ConvertImageToLocal item {0} - image url: {1}", item.Id, url); - await _providerManagerFactory().SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false); + await ProviderManager.SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false); item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None); @@ -2852,7 +2823,7 @@ namespace Emby.Server.Implementations.Library name = _fileSystem.GetValidFilename(name); - var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath; + var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, name); while (Directory.Exists(virtualFolderPath)) @@ -2871,7 +2842,7 @@ namespace Emby.Server.Implementations.Library } } - _libraryMonitorFactory().Stop(); + LibraryMonitor.Stop(); try { @@ -2906,7 +2877,7 @@ namespace Emby.Server.Implementations.Library { // Need to add a delay here or directory watchers may still pick up the changes await Task.Delay(1000).ConfigureAwait(false); - _libraryMonitorFactory().Start(); + LibraryMonitor.Start(); } } } @@ -2966,7 +2937,7 @@ namespace Emby.Server.Implementations.Library throw new FileNotFoundException("The network path does not exist."); } - var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath; + var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName); var shortcutFilename = Path.GetFileNameWithoutExtension(path); @@ -3009,7 +2980,7 @@ namespace Emby.Server.Implementations.Library throw new FileNotFoundException("The network path does not exist."); } - var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath; + var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName); var libraryOptions = CollectionFolder.GetLibraryOptions(virtualFolderPath); @@ -3062,7 +3033,7 @@ namespace Emby.Server.Implementations.Library throw new ArgumentNullException(nameof(name)); } - var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath; + var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var path = Path.Combine(rootFolderPath, name); @@ -3071,7 +3042,7 @@ namespace Emby.Server.Implementations.Library throw new FileNotFoundException("The media folder does not exist"); } - _libraryMonitorFactory().Stop(); + LibraryMonitor.Stop(); try { @@ -3091,7 +3062,7 @@ namespace Emby.Server.Implementations.Library { // Need to add a delay here or directory watchers may still pick up the changes await Task.Delay(1000).ConfigureAwait(false); - _libraryMonitorFactory().Start(); + LibraryMonitor.Start(); } } } @@ -3105,7 +3076,7 @@ namespace Emby.Server.Implementations.Library var removeList = new List(); - foreach (var contentType in ConfigurationManager.Configuration.ContentTypes) + foreach (var contentType in _configurationManager.Configuration.ContentTypes) { if (string.IsNullOrWhiteSpace(contentType.Name)) { @@ -3120,11 +3091,11 @@ namespace Emby.Server.Implementations.Library if (removeList.Count > 0) { - ConfigurationManager.Configuration.ContentTypes = ConfigurationManager.Configuration.ContentTypes + _configurationManager.Configuration.ContentTypes = _configurationManager.Configuration.ContentTypes .Except(removeList) .ToArray(); - ConfigurationManager.SaveConfiguration(); + _configurationManager.SaveConfiguration(); } } @@ -3135,7 +3106,7 @@ namespace Emby.Server.Implementations.Library throw new ArgumentNullException(nameof(mediaPath)); } - var rootFolderPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath; + var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath; var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName); if (!Directory.Exists(virtualFolderPath)) From 84b48eb69c1bd6c87dc33e359fe989cd88714f19 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 19:01:21 -0400 Subject: [PATCH 086/517] Convert MediaEncoder property to field --- Emby.Server.Implementations/ApplicationHost.cs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index aca1abf9fd..d3014a2d88 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -121,6 +121,7 @@ namespace Emby.Server.Implementations { private SqliteUserRepository _userRepository; private SqliteDisplayPreferencesRepository _displayPreferencesRepository; + private IMediaEncoder _mediaEncoder; private ISessionManager _sessionManager; private IHttpServer _httpServer; @@ -251,12 +252,6 @@ namespace Emby.Server.Implementations /// The user manager. public IUserManager UserManager { get; set; } - /// - /// Gets or sets the media encoder. - /// - /// The media encoder. - private IMediaEncoder MediaEncoder { get; set; } - public LocalizationManager LocalizationManager { get; set; } /// @@ -486,7 +481,7 @@ namespace Emby.Server.Implementations ConfigurationManager.ConfigurationUpdated += OnConfigurationUpdated; - MediaEncoder.SetFFmpegPath(); + _mediaEncoder.SetFFmpegPath(); Logger.LogInformation("ServerId: {0}", SystemId); @@ -685,7 +680,8 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(UserManager); - MediaEncoder = new MediaBrowser.MediaEncoding.Encoder.MediaEncoder( + // TODO: Add StartupOptions.FFmpegPath to IConfiguration so this doesn't need to be constructed manually + serviceCollection.AddSingleton(new MediaBrowser.MediaEncoding.Encoder.MediaEncoder( LoggerFactory.CreateLogger(), ServerConfigurationManager, FileSystemManager, @@ -693,8 +689,7 @@ namespace Emby.Server.Implementations LocalizationManager, Resolve, startupConfig, - StartupOptions.FFmpegPath); - serviceCollection.AddSingleton(MediaEncoder); + StartupOptions.FFmpegPath)); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); @@ -772,6 +767,7 @@ namespace Emby.Server.Implementations /// public void InitializeServices() { + _mediaEncoder = Resolve(); _sessionManager = Resolve(); _httpServer = Resolve(); @@ -1306,7 +1302,7 @@ namespace Emby.Server.Implementations ServerName = FriendlyName, LocalAddress = localAddress, SupportsLibraryMonitor = true, - EncoderLocation = MediaEncoder.EncoderLocation, + EncoderLocation = _mediaEncoder.EncoderLocation, SystemArchitecture = RuntimeInformation.OSArchitecture, SystemUpdateLevel = SystemUpdateLevel, PackageName = StartupOptions.PackageName From 4daa5436fc0d635fa8ae7b391efa7e1a8561d029 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 19:31:14 -0400 Subject: [PATCH 087/517] Register and construct IUserManager and IUserRepository correctly --- .../ApplicationHost.cs | 51 ++++--------------- .../Library/UserManager.cs | 26 ++++------ 2 files changed, 21 insertions(+), 56 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index d3014a2d88..9e570588a8 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -246,12 +246,6 @@ namespace Emby.Server.Implementations /// The server configuration manager. public IServerConfigurationManager ServerConfigurationManager => (IServerConfigurationManager)ConfigurationManager; - /// - /// Gets or sets the user manager. - /// - /// The user manager. - public IUserManager UserManager { get; set; } - public LocalizationManager LocalizationManager { get; set; } /// @@ -650,7 +644,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(new BdInfoExaminer(FileSystemManager)); - UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, () => UserManager); + UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, Resolve); serviceCollection.AddSingleton(UserDataManager); _displayPreferencesRepository = new SqliteDisplayPreferencesRepository( @@ -664,21 +658,11 @@ namespace Emby.Server.Implementations AuthenticationRepository = GetAuthenticationRepository(); serviceCollection.AddSingleton(AuthenticationRepository); - _userRepository = GetUserRepository(); - - UserManager = new UserManager( - LoggerFactory.CreateLogger(), - _userRepository, - XmlSerializer, - NetworkManager, - Resolve, - Resolve, - this, - JsonSerializer, - FileSystemManager, - cryptoProvider); + serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(UserManager); + // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required + serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); + serviceCollection.AddSingleton(); // TODO: Add StartupOptions.FFmpegPath to IConfiguration so this doesn't need to be constructed manually serviceCollection.AddSingleton(new MediaBrowser.MediaEncoding.Encoder.MediaEncoder( @@ -771,6 +755,7 @@ namespace Emby.Server.Implementations _sessionManager = Resolve(); _httpServer = Resolve(); + ((SqliteUserRepository)Resolve()).Initialize(); ((ActivityRepository)Resolve()).Initialize(); _displayPreferencesRepository.Initialize(); @@ -778,11 +763,12 @@ namespace Emby.Server.Implementations SetStaticProperties(); - ((UserManager)UserManager).Initialize(); + var userManager = (UserManager)Resolve(); + userManager.Initialize(); ((UserDataManager)UserDataManager).Repository = userDataRepo; - ((SqliteItemRepository)Resolve()).Initialize(userDataRepo, UserManager); + ((SqliteItemRepository)Resolve()).Initialize(userDataRepo, userManager); FindParts(); } @@ -853,21 +839,6 @@ namespace Emby.Server.Implementations } } - /// - /// Gets the user repository. - /// - /// . - private SqliteUserRepository GetUserRepository() - { - var repo = new SqliteUserRepository( - LoggerFactory.CreateLogger(), - ApplicationPaths); - - repo.Initialize(); - - return repo; - } - private IAuthenticationRepository GetAuthenticationRepository() { var repo = new AuthenticationRepository(LoggerFactory, ServerConfigurationManager); @@ -889,7 +860,7 @@ namespace Emby.Server.Implementations BaseItem.ProviderManager = Resolve(); BaseItem.LocalizationManager = LocalizationManager; BaseItem.ItemRepository = Resolve(); - User.UserManager = UserManager; + User.UserManager = Resolve(); BaseItem.FileSystem = FileSystemManager; BaseItem.UserDataManager = UserDataManager; BaseItem.ChannelManager = Resolve(); @@ -984,7 +955,7 @@ namespace Emby.Server.Implementations Resolve().AddParts(GetExports()); Resolve().AddParts(GetExports(), GetExports()); - UserManager.AddParts(GetExports(), GetExports()); + Resolve().AddParts(GetExports(), GetExports()); IsoManager.AddParts(GetExports()); } diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 7b17cc913f..64193a8ec2 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -44,22 +44,14 @@ namespace Emby.Server.Implementations.Library { private readonly object _policySyncLock = new object(); private readonly object _configSyncLock = new object(); - /// - /// The logger. - /// - private readonly ILogger _logger; - /// - /// Gets the active user repository. - /// - /// The user repository. + private readonly ILogger _logger; private readonly IUserRepository _userRepository; private readonly IXmlSerializer _xmlSerializer; private readonly IJsonSerializer _jsonSerializer; private readonly INetworkManager _networkManager; - - private readonly Func _imageProcessorFactory; - private readonly Func _dtoServiceFactory; + private readonly IImageProcessor _imageProcessor; + private readonly Lazy _dtoServiceFactory; private readonly IServerApplicationHost _appHost; private readonly IFileSystem _fileSystem; private readonly ICryptoProvider _cryptoProvider; @@ -74,13 +66,15 @@ namespace Emby.Server.Implementations.Library private IPasswordResetProvider[] _passwordResetProviders; private DefaultPasswordResetProvider _defaultPasswordResetProvider; + private IDtoService DtoService => _dtoServiceFactory.Value; + public UserManager( ILogger logger, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, - Func imageProcessorFactory, - Func dtoServiceFactory, + IImageProcessor imageProcessor, + Lazy dtoServiceFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer, IFileSystem fileSystem, @@ -90,7 +84,7 @@ namespace Emby.Server.Implementations.Library _userRepository = userRepository; _xmlSerializer = xmlSerializer; _networkManager = networkManager; - _imageProcessorFactory = imageProcessorFactory; + _imageProcessor = imageProcessor; _dtoServiceFactory = dtoServiceFactory; _appHost = appHost; _jsonSerializer = jsonSerializer; @@ -600,7 +594,7 @@ namespace Emby.Server.Implementations.Library try { - _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user); + DtoService.AttachPrimaryImageAspectRatio(dto, user); } catch (Exception ex) { @@ -625,7 +619,7 @@ namespace Emby.Server.Implementations.Library { try { - return _imageProcessorFactory().GetImageCacheTag(item, image); + return _imageProcessor.GetImageCacheTag(item, image); } catch (Exception ex) { From a5234dfd886e9938ede838dcee79ff81d2139f57 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 19:36:27 -0400 Subject: [PATCH 088/517] Register and construct IAuthenticationRepository correctly --- Emby.Server.Implementations/ApplicationHost.cs | 15 ++------------- .../Security/AuthenticationRepository.cs | 4 ++-- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 9e570588a8..86b267303e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -254,8 +254,6 @@ namespace Emby.Server.Implementations /// The user data repository. private IUserDataManager UserDataManager { get; set; } - private IAuthenticationRepository AuthenticationRepository { get; set; } - /// /// Gets the installation manager. /// @@ -655,8 +653,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); - AuthenticationRepository = GetAuthenticationRepository(); - serviceCollection.AddSingleton(AuthenticationRepository); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -755,6 +752,7 @@ namespace Emby.Server.Implementations _sessionManager = Resolve(); _httpServer = Resolve(); + ((AuthenticationRepository)Resolve()).Initialize(); ((SqliteUserRepository)Resolve()).Initialize(); ((ActivityRepository)Resolve()).Initialize(); _displayPreferencesRepository.Initialize(); @@ -839,15 +837,6 @@ namespace Emby.Server.Implementations } } - private IAuthenticationRepository GetAuthenticationRepository() - { - var repo = new AuthenticationRepository(LoggerFactory, ServerConfigurationManager); - - repo.Initialize(); - - return repo; - } - /// /// Dirty hacks. /// diff --git a/Emby.Server.Implementations/Security/AuthenticationRepository.cs b/Emby.Server.Implementations/Security/AuthenticationRepository.cs index 1ef5c4b996..4e4029f06f 100644 --- a/Emby.Server.Implementations/Security/AuthenticationRepository.cs +++ b/Emby.Server.Implementations/Security/AuthenticationRepository.cs @@ -15,8 +15,8 @@ namespace Emby.Server.Implementations.Security { public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository { - public AuthenticationRepository(ILoggerFactory loggerFactory, IServerConfigurationManager config) - : base(loggerFactory.CreateLogger(nameof(AuthenticationRepository))) + public AuthenticationRepository(ILogger logger, IServerConfigurationManager config) + : base(logger) { DbFilePath = Path.Combine(config.ApplicationPaths.DataPath, "authentication.db"); } From 5827f0f5a96574f1c87904a866890b998cab48a7 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 19:40:53 -0400 Subject: [PATCH 089/517] Register IDisplayPreferencesRepository correctly --- Emby.Server.Implementations/ApplicationHost.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 86b267303e..875ed62fe1 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -120,7 +120,6 @@ namespace Emby.Server.Implementations public abstract class ApplicationHost : IServerApplicationHost, IDisposable { private SqliteUserRepository _userRepository; - private SqliteDisplayPreferencesRepository _displayPreferencesRepository; private IMediaEncoder _mediaEncoder; private ISessionManager _sessionManager; private IHttpServer _httpServer; @@ -645,11 +644,7 @@ namespace Emby.Server.Implementations UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, Resolve); serviceCollection.AddSingleton(UserDataManager); - _displayPreferencesRepository = new SqliteDisplayPreferencesRepository( - LoggerFactory.CreateLogger(), - ApplicationPaths, - FileSystemManager); - serviceCollection.AddSingleton(_displayPreferencesRepository); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -752,10 +747,10 @@ namespace Emby.Server.Implementations _sessionManager = Resolve(); _httpServer = Resolve(); + ((SqliteDisplayPreferencesRepository)Resolve()).Initialize(); ((AuthenticationRepository)Resolve()).Initialize(); ((SqliteUserRepository)Resolve()).Initialize(); ((ActivityRepository)Resolve()).Initialize(); - _displayPreferencesRepository.Initialize(); var userDataRepo = new SqliteUserDataRepository(LoggerFactory.CreateLogger(), ApplicationPaths); @@ -1628,11 +1623,9 @@ namespace Emby.Server.Implementations } _userRepository?.Dispose(); - _displayPreferencesRepository?.Dispose(); } _userRepository = null; - _displayPreferencesRepository = null; _disposed = true; } From 615717e562f98c5cbd4e9ad648380a555d44d774 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 19:57:26 -0400 Subject: [PATCH 090/517] Register and construct IUserDataManager and IUserDataRepository correctly --- .../ApplicationHost.cs | 17 ++------- .../Library/UserDataManager.cs | 37 +++++++++---------- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 875ed62fe1..ea580bad85 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -247,12 +247,6 @@ namespace Emby.Server.Implementations public LocalizationManager LocalizationManager { get; set; } - /// - /// Gets or sets the user data repository. - /// - /// The user data repository. - private IUserDataManager UserDataManager { get; set; } - /// /// Gets the installation manager. /// @@ -641,8 +635,8 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(new BdInfoExaminer(FileSystemManager)); - UserDataManager = new UserDataManager(LoggerFactory, ServerConfigurationManager, Resolve); - serviceCollection.AddSingleton(UserDataManager); + serviceCollection.AddSingleton(); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -752,15 +746,12 @@ namespace Emby.Server.Implementations ((SqliteUserRepository)Resolve()).Initialize(); ((ActivityRepository)Resolve()).Initialize(); - var userDataRepo = new SqliteUserDataRepository(LoggerFactory.CreateLogger(), ApplicationPaths); - SetStaticProperties(); var userManager = (UserManager)Resolve(); userManager.Initialize(); - ((UserDataManager)UserDataManager).Repository = userDataRepo; - + var userDataRepo = (SqliteUserDataRepository)Resolve(); ((SqliteItemRepository)Resolve()).Initialize(userDataRepo, userManager); FindParts(); @@ -846,7 +837,7 @@ namespace Emby.Server.Implementations BaseItem.ItemRepository = Resolve(); User.UserManager = Resolve(); BaseItem.FileSystem = FileSystemManager; - BaseItem.UserDataManager = UserDataManager; + BaseItem.UserDataManager = Resolve(); BaseItem.ChannelManager = Resolve(); Video.LiveTvManager = Resolve(); Folder.UserViewManager = Resolve(); diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs index 071681b08f..a9772a078d 100644 --- a/Emby.Server.Implementations/Library/UserDataManager.cs +++ b/Emby.Server.Implementations/Library/UserDataManager.cs @@ -28,25 +28,24 @@ namespace Emby.Server.Implementations.Library private readonly ILogger _logger; private readonly IServerConfigurationManager _config; - - private Func _userManager; - - public UserDataManager(ILoggerFactory loggerFactory, IServerConfigurationManager config, Func userManager) + private readonly IUserManager _userManager; + private readonly IUserDataRepository _repository; + + public UserDataManager( + ILogger logger, + IServerConfigurationManager config, + IUserManager userManager, + IUserDataRepository repository) { + _logger = logger; _config = config; - _logger = loggerFactory.CreateLogger(GetType().Name); _userManager = userManager; + _repository = repository; } - /// - /// Gets or sets the repository. - /// - /// The repository. - public IUserDataRepository Repository { get; set; } - public void SaveUserData(Guid userId, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken) { - var user = _userManager().GetUserById(userId); + var user = _userManager.GetUserById(userId); SaveUserData(user, item, userData, reason, cancellationToken); } @@ -71,7 +70,7 @@ namespace Emby.Server.Implementations.Library foreach (var key in keys) { - Repository.SaveUserData(userId, key, userData, cancellationToken); + _repository.SaveUserData(userId, key, userData, cancellationToken); } var cacheKey = GetCacheKey(userId, item.Id); @@ -96,9 +95,9 @@ namespace Emby.Server.Implementations.Library /// public void SaveAllUserData(Guid userId, UserItemData[] userData, CancellationToken cancellationToken) { - var user = _userManager().GetUserById(userId); + var user = _userManager.GetUserById(userId); - Repository.SaveAllUserData(user.InternalId, userData, cancellationToken); + _repository.SaveAllUserData(user.InternalId, userData, cancellationToken); } /// @@ -108,14 +107,14 @@ namespace Emby.Server.Implementations.Library /// public List GetAllUserData(Guid userId) { - var user = _userManager().GetUserById(userId); + var user = _userManager.GetUserById(userId); - return Repository.GetAllUserData(user.InternalId); + return _repository.GetAllUserData(user.InternalId); } public UserItemData GetUserData(Guid userId, Guid itemId, List keys) { - var user = _userManager().GetUserById(userId); + var user = _userManager.GetUserById(userId); return GetUserData(user, itemId, keys); } @@ -131,7 +130,7 @@ namespace Emby.Server.Implementations.Library private UserItemData GetUserDataInternal(long internalUserId, List keys) { - var userData = Repository.GetUserData(internalUserId, keys); + var userData = _repository.GetUserData(internalUserId, keys); if (userData != null) { From cbc0224aafa1e0a4c9d52f55e03ab944ff3b7132 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 20:00:55 -0400 Subject: [PATCH 091/517] Register IStreamHelper, IInstallationManager, IZipClient, IHttpResultFactory and IBlurayExaminer correctly --- Emby.Server.Implementations/ApplicationHost.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ea580bad85..e951ab1146 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -610,7 +610,7 @@ namespace Emby.Server.Implementations ProcessFactory = new ProcessFactory(); serviceCollection.AddSingleton(ProcessFactory); - serviceCollection.AddSingleton(typeof(IStreamHelper), typeof(StreamHelper)); + serviceCollection.AddSingleton(); var cryptoProvider = new CryptographyProvider(); serviceCollection.AddSingleton(cryptoProvider); @@ -618,11 +618,11 @@ namespace Emby.Server.Implementations SocketFactory = new SocketFactory(); serviceCollection.AddSingleton(SocketFactory); - serviceCollection.AddSingleton(typeof(IInstallationManager), typeof(InstallationManager)); + serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(typeof(IZipClient), typeof(ZipClient)); + serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(typeof(IHttpResultFactory), typeof(HttpResultFactory)); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(this); serviceCollection.AddSingleton(ApplicationPaths); @@ -633,7 +633,7 @@ namespace Emby.Server.Implementations await LocalizationManager.LoadAll().ConfigureAwait(false); serviceCollection.AddSingleton(LocalizationManager); - serviceCollection.AddSingleton(new BdInfoExaminer(FileSystemManager)); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); From 5d648bf54f3c0fe503f8fdebb58a72b8c5e64673 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 20:21:48 -0400 Subject: [PATCH 092/517] Register and construct ILocalizationManager correctly --- .../ApplicationHost.cs | 33 ++++++++++--------- .../Localization/LocalizationManager.cs | 3 -- Jellyfin.Server/Program.cs | 2 +- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index e951ab1146..75a2b194a6 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -245,8 +245,6 @@ namespace Emby.Server.Implementations /// The server configuration manager. public IServerConfigurationManager ServerConfigurationManager => (IServerConfigurationManager)ConfigurationManager; - public LocalizationManager LocalizationManager { get; set; } - /// /// Gets the installation manager. /// @@ -629,9 +627,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(ServerConfigurationManager); - LocalizationManager = new LocalizationManager(ServerConfigurationManager, JsonSerializer, LoggerFactory.CreateLogger()); - await LocalizationManager.LoadAll().ConfigureAwait(false); - serviceCollection.AddSingleton(LocalizationManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -651,15 +647,16 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(); // TODO: Add StartupOptions.FFmpegPath to IConfiguration so this doesn't need to be constructed manually - serviceCollection.AddSingleton(new MediaBrowser.MediaEncoding.Encoder.MediaEncoder( - LoggerFactory.CreateLogger(), - ServerConfigurationManager, - FileSystemManager, - ProcessFactory, - LocalizationManager, - Resolve, - startupConfig, - StartupOptions.FFmpegPath)); + serviceCollection.AddSingleton(provider => + new MediaBrowser.MediaEncoding.Encoder.MediaEncoder( + provider.GetRequiredService>(), + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService(), + provider.GetRequiredService, + provider.GetRequiredService(), + StartupOptions.FFmpegPath)); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); @@ -735,8 +732,12 @@ namespace Emby.Server.Implementations /// /// Create services registered with the service container that need to be initialized at application startup. /// - public void InitializeServices() + /// A task representing the service initialization operation. + public async Task InitializeServices() { + var localizationManager = (LocalizationManager)Resolve(); + await localizationManager.LoadAll().ConfigureAwait(false); + _mediaEncoder = Resolve(); _sessionManager = Resolve(); _httpServer = Resolve(); @@ -833,7 +834,7 @@ namespace Emby.Server.Implementations BaseItem.ConfigurationManager = ServerConfigurationManager; BaseItem.LibraryManager = Resolve(); BaseItem.ProviderManager = Resolve(); - BaseItem.LocalizationManager = LocalizationManager; + BaseItem.LocalizationManager = Resolve(); BaseItem.ItemRepository = Resolve(); User.UserManager = Resolve(); BaseItem.FileSystem = FileSystemManager; diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index bda43e832a..e2a634e1a4 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -23,9 +23,6 @@ namespace Emby.Server.Implementations.Localization private static readonly Assembly _assembly = typeof(LocalizationManager).Assembly; private static readonly string[] _unratedValues = { "n/a", "unrated", "not rated" }; - /// - /// The _configuration manager. - /// private readonly IServerConfigurationManager _configurationManager; private readonly IJsonSerializer _jsonSerializer; private readonly ILogger _logger; diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 5e9c15e20e..83170c6ae0 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -208,7 +208,7 @@ namespace Jellyfin.Server // Re-use the web host service provider in the app host since ASP.NET doesn't allow a custom service collection. appHost.ServiceProvider = webHost.Services; - appHost.InitializeServices(); + await appHost.InitializeServices().ConfigureAwait(false); Migrations.MigrationRunner.Run(appHost, _loggerFactory); try From aee6a1b4764869143edab160eef4d6fb111032a2 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 20:40:50 -0400 Subject: [PATCH 093/517] Remove unnecessary async and parameter from ApplicationHost initialization method --- Emby.Server.Implementations/ApplicationHost.cs | 6 +++--- Jellyfin.Server/Program.cs | 2 +- MediaBrowser.Common/IApplicationHost.cs | 4 +--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 75a2b194a6..4597b65f3d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -500,7 +500,7 @@ namespace Emby.Server.Implementations } /// - public async Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig) + public void Init(IServiceCollection serviceCollection) { HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; @@ -533,7 +533,7 @@ namespace Emby.Server.Implementations DiscoverTypes(); - await RegisterServices(serviceCollection, startupConfig).ConfigureAwait(false); + RegisterServices(serviceCollection); } public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func next) @@ -566,7 +566,7 @@ namespace Emby.Server.Implementations /// /// Registers services/resources with the service collection that will be available via DI. /// - protected async Task RegisterServices(IServiceCollection serviceCollection, IConfiguration startupConfig) + protected void RegisterServices(IServiceCollection serviceCollection) { var imageEncoderType = SkiaEncoder.IsNativeLibAvailable() ? typeof(SkiaEncoder) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 83170c6ae0..56017cf897 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -202,7 +202,7 @@ namespace Jellyfin.Server } ServiceCollection serviceCollection = new ServiceCollection(); - await appHost.InitAsync(serviceCollection, startupConfig).ConfigureAwait(false); + appHost.Init(serviceCollection); var webHost = CreateWebHostBuilder(appHost, serviceCollection, options, startupConfig, appPaths).Build(); diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index 0e282cf538..904138381c 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -125,9 +125,7 @@ namespace MediaBrowser.Common /// Initializes this instance. /// /// The service collection. - /// The configuration to use for initialization. - /// A task. - Task InitAsync(IServiceCollection serviceCollection, IConfiguration startupConfig); + void Init(IServiceCollection serviceCollection); /// /// Creates the instance. From 3f2f95d8774df3dc27e9a24d89e7f7d6f57e2886 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 20:42:11 -0400 Subject: [PATCH 094/517] Register IProcessFactory, ICryptoProvider and ISocketFactory correctly --- Emby.Server.Implementations/ApplicationHost.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 4597b65f3d..6c1719ac10 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -253,12 +253,8 @@ namespace Emby.Server.Implementations public IStartupOptions StartupOptions { get; } - protected IProcessFactory ProcessFactory { get; private set; } - protected readonly IXmlSerializer XmlSerializer; - protected ISocketFactory SocketFactory { get; private set; } - protected ITaskManager TaskManager { get; private set; } public IHttpClient HttpClient { get; private set; } @@ -605,16 +601,13 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(XmlSerializer); - ProcessFactory = new ProcessFactory(); - serviceCollection.AddSingleton(ProcessFactory); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - var cryptoProvider = new CryptographyProvider(); - serviceCollection.AddSingleton(cryptoProvider); + serviceCollection.AddSingleton(); - SocketFactory = new SocketFactory(); - serviceCollection.AddSingleton(SocketFactory); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); @@ -1539,7 +1532,7 @@ namespace Emby.Server.Implementations throw new NotSupportedException(); } - var process = ProcessFactory.Create(new ProcessOptions + var process = Resolve().Create(new ProcessOptions { FileName = url, EnableRaisingEvents = true, From adf0e8d3fd8724a78e97fc0f4874beef67e5b891 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 21:00:11 -0400 Subject: [PATCH 095/517] Register and construct ITaskManager and IIsoManager correctly --- .../ApplicationHost.cs | 12 +++-------- .../ScheduledTasks/TaskManager.cs | 20 +++---------------- 2 files changed, 6 insertions(+), 26 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 6c1719ac10..0fde273c59 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -255,16 +255,12 @@ namespace Emby.Server.Implementations protected readonly IXmlSerializer XmlSerializer; - protected ITaskManager TaskManager { get; private set; } - public IHttpClient HttpClient { get; private set; } protected INetworkManager NetworkManager { get; set; } public IJsonSerializer JsonSerializer { get; private set; } - protected IIsoManager IsoManager { get; private set; } - /// /// Initializes a new instance of the class. /// @@ -593,11 +589,9 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(NetworkManager); - IsoManager = new IsoManager(); - serviceCollection.AddSingleton(IsoManager); + serviceCollection.AddSingleton(); - TaskManager = new TaskManager(ApplicationPaths, JsonSerializer, LoggerFactory, FileSystemManager); - serviceCollection.AddSingleton(TaskManager); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(XmlSerializer); @@ -926,7 +920,7 @@ namespace Emby.Server.Implementations Resolve().AddParts(GetExports(), GetExports()); Resolve().AddParts(GetExports(), GetExports()); - IsoManager.AddParts(GetExports()); + Resolve().AddParts(GetExports()); } private IPlugin LoadPlugin(IPlugin plugin) diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs index ecf58dbc0e..6ffa581a9c 100644 --- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs +++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs @@ -32,22 +32,8 @@ namespace Emby.Server.Implementations.ScheduledTasks private readonly ConcurrentQueue> _taskQueue = new ConcurrentQueue>(); - /// - /// Gets or sets the json serializer. - /// - /// The json serializer. private readonly IJsonSerializer _jsonSerializer; - - /// - /// Gets or sets the application paths. - /// - /// The application paths. private readonly IApplicationPaths _applicationPaths; - - /// - /// Gets the logger. - /// - /// The logger. private readonly ILogger _logger; private readonly IFileSystem _fileSystem; @@ -56,17 +42,17 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// The application paths. /// The json serializer. - /// The logger factory. + /// The logger. /// The filesystem manager. public TaskManager( IApplicationPaths applicationPaths, IJsonSerializer jsonSerializer, - ILoggerFactory loggerFactory, + ILogger logger, IFileSystem fileSystem) { _applicationPaths = applicationPaths; _jsonSerializer = jsonSerializer; - _logger = loggerFactory.CreateLogger(nameof(TaskManager)); + _logger = logger; _fileSystem = fileSystem; ScheduledTasks = Array.Empty(); From e16c16dd51c62b1ad004979d729e4ef022359505 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 21:18:09 -0400 Subject: [PATCH 096/517] Register and construct IHttpClient correctly --- Emby.Server.Implementations/ApplicationHost.cs | 18 +++++------------- .../HttpClientManager/HttpClientManager.cs | 9 +++++---- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 0fde273c59..5592d39197 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -123,6 +123,7 @@ namespace Emby.Server.Implementations private IMediaEncoder _mediaEncoder; private ISessionManager _sessionManager; private IHttpServer _httpServer; + private IHttpClient _httpClient; /// /// Gets a value indicating whether this instance can self restart. @@ -255,8 +256,6 @@ namespace Emby.Server.Implementations protected readonly IXmlSerializer XmlSerializer; - public IHttpClient HttpClient { get; private set; } - protected INetworkManager NetworkManager { get; set; } public IJsonSerializer JsonSerializer { get; private set; } @@ -363,10 +362,7 @@ namespace Emby.Server.Implementations } } - /// - /// Gets the name. - /// - /// The name. + /// public string Name => ApplicationProductName; /// @@ -580,12 +576,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(FileSystemManager); serviceCollection.AddSingleton(); - HttpClient = new HttpClientManager.HttpClientManager( - ApplicationPaths, - LoggerFactory.CreateLogger(), - FileSystemManager, - () => ApplicationUserAgent); - serviceCollection.AddSingleton(HttpClient); + serviceCollection.AddSingleton(); serviceCollection.AddSingleton(NetworkManager); @@ -728,6 +719,7 @@ namespace Emby.Server.Implementations _mediaEncoder = Resolve(); _sessionManager = Resolve(); _httpServer = Resolve(); + _httpClient = Resolve(); ((SqliteDisplayPreferencesRepository)Resolve()).Initialize(); ((AuthenticationRepository)Resolve()).Initialize(); @@ -1423,7 +1415,7 @@ namespace Emby.Server.Implementations try { - using (var response = await HttpClient.SendAsync( + using (var response = await _httpClient.SendAsync( new HttpRequestOptions { Url = apiUrl, diff --git a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs index 882bfe2f6e..d66bb7638b 100644 --- a/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs +++ b/Emby.Server.Implementations/HttpClientManager/HttpClientManager.cs @@ -6,6 +6,7 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Threading.Tasks; +using MediaBrowser.Common; using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; @@ -24,7 +25,7 @@ namespace Emby.Server.Implementations.HttpClientManager private readonly ILogger _logger; private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; - private readonly Func _defaultUserAgentFn; + private readonly IApplicationHost _appHost; /// /// Holds a dictionary of http clients by host. Use GetHttpClient(host) to retrieve or create a client for web requests. @@ -40,12 +41,12 @@ namespace Emby.Server.Implementations.HttpClientManager IApplicationPaths appPaths, ILogger logger, IFileSystem fileSystem, - Func defaultUserAgentFn) + IApplicationHost appHost) { _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _fileSystem = fileSystem; _appPaths = appPaths ?? throw new ArgumentNullException(nameof(appPaths)); - _defaultUserAgentFn = defaultUserAgentFn; + _appHost = appHost; } /// @@ -91,7 +92,7 @@ namespace Emby.Server.Implementations.HttpClientManager if (options.EnableDefaultUserAgent && !request.Headers.TryGetValues(HeaderNames.UserAgent, out _)) { - request.Headers.Add(HeaderNames.UserAgent, _defaultUserAgentFn()); + request.Headers.Add(HeaderNames.UserAgent, _appHost.ApplicationUserAgent); } switch (options.DecompressionMethod) From 710767fbf2c80491448e3c978eec6b2745c9e4db Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 21:27:48 -0400 Subject: [PATCH 097/517] Add deprecation warning message for injecting ILogger --- Emby.Server.Implementations/ApplicationHost.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 5592d39197..b724dc3201 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -570,8 +570,12 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(JsonSerializer); - // TODO: Support for injecting ILogger should be deprecated in favour of ILogger and this removed - serviceCollection.AddSingleton(Logger); + // TODO: Remove support for injecting ILogger completely + serviceCollection.AddSingleton((provider) => + { + Logger.LogWarning("Injecting ILogger directly is deprecated and should be replaced with ILogger"); + return Logger; + }); serviceCollection.AddSingleton(FileSystemManager); serviceCollection.AddSingleton(); From 809cf3a0c288713fd0ed0cc0ace6f7bb90a90ca2 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 21:33:57 -0400 Subject: [PATCH 098/517] Register IJsonSerializer correctly --- Emby.Server.Implementations/ApplicationHost.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index b724dc3201..bae97c17ec 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -258,8 +258,6 @@ namespace Emby.Server.Implementations protected INetworkManager NetworkManager { get; set; } - public IJsonSerializer JsonSerializer { get; private set; } - /// /// Initializes a new instance of the class. /// @@ -500,8 +498,6 @@ namespace Emby.Server.Implementations HttpsPort = ServerConfiguration.DefaultHttpsPort; } - JsonSerializer = new JsonSerializer(); - if (Plugins != null) { var pluginBuilder = new StringBuilder(); @@ -568,7 +564,7 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(ApplicationPaths); - serviceCollection.AddSingleton(JsonSerializer); + serviceCollection.AddSingleton(); // TODO: Remove support for injecting ILogger completely serviceCollection.AddSingleton((provider) => @@ -813,7 +809,7 @@ namespace Emby.Server.Implementations private void SetStaticProperties() { // For now there's no real way to inject these properly - BaseItem.Logger = LoggerFactory.CreateLogger("BaseItem"); + BaseItem.Logger = Resolve>(); BaseItem.ConfigurationManager = ServerConfigurationManager; BaseItem.LibraryManager = Resolve(); BaseItem.ProviderManager = Resolve(); @@ -829,7 +825,7 @@ namespace Emby.Server.Implementations UserView.CollectionManager = Resolve(); BaseItem.MediaSourceManager = Resolve(); CollectionFolder.XmlSerializer = XmlSerializer; - CollectionFolder.JsonSerializer = JsonSerializer; + CollectionFolder.JsonSerializer = Resolve(); CollectionFolder.ApplicationHost = this; AuthenticatedAttribute.AuthService = Resolve(); } From 241d0ae65cca0ffdd92b7c366d692acaa71cd211 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 23:14:35 -0400 Subject: [PATCH 099/517] Inject IStartupOptions into StartupWizard --- Emby.Server.Implementations/ApplicationHost.cs | 2 ++ .../EntryPoints/StartupWizard.cs | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index bae97c17ec..0620469c0f 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -557,6 +557,8 @@ namespace Emby.Server.Implementations : typeof(NullImageEncoder); serviceCollection.AddSingleton(typeof(IImageEncoder), imageEncoderType); + serviceCollection.AddSingleton(_startupOptions); + serviceCollection.AddMemoryCache(); serviceCollection.AddSingleton(ConfigurationManager); diff --git a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs index 8e97719311..af1604aa6e 100644 --- a/Emby.Server.Implementations/EntryPoints/StartupWizard.cs +++ b/Emby.Server.Implementations/EntryPoints/StartupWizard.cs @@ -16,17 +16,25 @@ namespace Emby.Server.Implementations.EntryPoints private readonly IServerApplicationHost _appHost; private readonly IConfiguration _appConfig; private readonly IServerConfigurationManager _config; + private readonly IStartupOptions _startupOptions; /// /// Initializes a new instance of the class. /// /// The application host. + /// The application configuration. /// The configuration manager. - public StartupWizard(IServerApplicationHost appHost, IConfiguration appConfig, IServerConfigurationManager config) + /// The application startup options. + public StartupWizard( + IServerApplicationHost appHost, + IConfiguration appConfig, + IServerConfigurationManager config, + IStartupOptions startupOptions) { _appHost = appHost; _appConfig = appConfig; _config = config; + _startupOptions = startupOptions; } /// @@ -47,9 +55,7 @@ namespace Emby.Server.Implementations.EntryPoints } else if (_config.Configuration.AutoRunWebApp) { - var options = ((ApplicationHost)_appHost).StartupOptions; - - if (!options.NoAutoRunWebApp) + if (!_startupOptions.NoAutoRunWebApp) { BrowserLauncher.OpenWebApp(_appHost); } From 735d6c8ad531904c24650d88dd07ef3e57ded46a Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 4 Apr 2020 23:18:11 -0400 Subject: [PATCH 100/517] Convert properties in ApplicationHost to private readonly fields, where possible --- .../ApplicationHost.cs | 67 +++++++------------ .../Data/SqliteItemRepository.cs | 2 +- Jellyfin.Server/CoreAppHost.cs | 3 - 3 files changed, 27 insertions(+), 45 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 0620469c0f..06b6fec555 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -119,17 +119,21 @@ namespace Emby.Server.Implementations /// public abstract class ApplicationHost : IServerApplicationHost, IDisposable { - private SqliteUserRepository _userRepository; + private readonly IFileSystem _fileSystemManager; + private readonly INetworkManager _networkManager; + private readonly IXmlSerializer _xmlSerializer; + private readonly IStartupOptions _startupOptions; + private IMediaEncoder _mediaEncoder; private ISessionManager _sessionManager; private IHttpServer _httpServer; private IHttpClient _httpClient; + private IInstallationManager _installationManager; /// /// Gets a value indicating whether this instance can self restart. /// - /// true if this instance can self restart; otherwise, false. - public abstract bool CanSelfRestart { get; } + public bool CanSelfRestart => _startupOptions.RestartPath != null; public virtual bool CanLaunchWebBrowser { @@ -140,7 +144,7 @@ namespace Emby.Server.Implementations return false; } - if (StartupOptions.IsService) + if (_startupOptions.IsService) { return false; } @@ -210,8 +214,6 @@ namespace Emby.Server.Implementations /// The configuration manager. protected IConfigurationManager ConfigurationManager { get; set; } - public IFileSystem FileSystemManager { get; set; } - /// public PackageVersionClass SystemUpdateLevel { @@ -246,18 +248,6 @@ namespace Emby.Server.Implementations /// The server configuration manager. public IServerConfigurationManager ServerConfigurationManager => (IServerConfigurationManager)ConfigurationManager; - /// - /// Gets the installation manager. - /// - /// The installation manager. - protected IInstallationManager InstallationManager { get; private set; } - - public IStartupOptions StartupOptions { get; } - - protected readonly IXmlSerializer XmlSerializer; - - protected INetworkManager NetworkManager { get; set; } - /// /// Initializes a new instance of the class. /// @@ -268,24 +258,24 @@ namespace Emby.Server.Implementations IFileSystem fileSystem, INetworkManager networkManager) { - XmlSerializer = new MyXmlSerializer(); + _xmlSerializer = new MyXmlSerializer(); - NetworkManager = networkManager; + _networkManager = networkManager; networkManager.LocalSubnetsFn = GetConfiguredLocalSubnets; ApplicationPaths = applicationPaths; LoggerFactory = loggerFactory; - FileSystemManager = fileSystem; + _fileSystemManager = fileSystem; - ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, XmlSerializer, FileSystemManager); + ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, _xmlSerializer, _fileSystemManager); Logger = LoggerFactory.CreateLogger("App"); - StartupOptions = options; + _startupOptions = options; fileSystem.AddShortcutHandler(new MbLinkShortcutHandler(fileSystem)); - NetworkManager.NetworkChanged += OnNetworkChanged; + _networkManager.NetworkChanged += OnNetworkChanged; CertificateInfo = new CertificateInfo { @@ -575,18 +565,18 @@ namespace Emby.Server.Implementations return Logger; }); - serviceCollection.AddSingleton(FileSystemManager); + serviceCollection.AddSingleton(_fileSystemManager); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(NetworkManager); + serviceCollection.AddSingleton(_networkManager); serviceCollection.AddSingleton(); serviceCollection.AddSingleton(); - serviceCollection.AddSingleton(XmlSerializer); + serviceCollection.AddSingleton(_xmlSerializer); serviceCollection.AddSingleton(); @@ -636,7 +626,7 @@ namespace Emby.Server.Implementations provider.GetRequiredService(), provider.GetRequiredService, provider.GetRequiredService(), - StartupOptions.FFmpegPath)); + _startupOptions.FFmpegPath)); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); @@ -736,6 +726,8 @@ namespace Emby.Server.Implementations var userDataRepo = (SqliteUserDataRepository)Resolve(); ((SqliteItemRepository)Resolve()).Initialize(userDataRepo, userManager); + Resolve().PluginInstalled += PluginInstalled; + FindParts(); } @@ -818,7 +810,7 @@ namespace Emby.Server.Implementations BaseItem.LocalizationManager = Resolve(); BaseItem.ItemRepository = Resolve(); User.UserManager = Resolve(); - BaseItem.FileSystem = FileSystemManager; + BaseItem.FileSystem = _fileSystemManager; BaseItem.UserDataManager = Resolve(); BaseItem.ChannelManager = Resolve(); Video.LiveTvManager = Resolve(); @@ -826,7 +818,7 @@ namespace Emby.Server.Implementations UserView.TVSeriesManager = Resolve(); UserView.CollectionManager = Resolve(); BaseItem.MediaSourceManager = Resolve(); - CollectionFolder.XmlSerializer = XmlSerializer; + CollectionFolder.XmlSerializer = _xmlSerializer; CollectionFolder.JsonSerializer = Resolve(); CollectionFolder.ApplicationHost = this; AuthenticatedAttribute.AuthService = Resolve(); @@ -872,9 +864,6 @@ namespace Emby.Server.Implementations /// private void FindParts() { - InstallationManager = ServiceProvider.GetService(); - InstallationManager.PluginInstalled += PluginInstalled; - if (!ServerConfigurationManager.Configuration.IsPortAuthorized) { ServerConfigurationManager.Configuration.IsPortAuthorized = true; @@ -1210,7 +1199,7 @@ namespace Emby.Server.Implementations IsShuttingDown = IsShuttingDown, Version = ApplicationVersionString, WebSocketPortNumber = HttpPort, - CompletedInstallations = InstallationManager.CompletedInstallations.ToArray(), + CompletedInstallations = _installationManager.CompletedInstallations.ToArray(), Id = SystemId, ProgramDataPath = ApplicationPaths.ProgramDataPath, WebPath = ApplicationPaths.WebPath, @@ -1233,12 +1222,12 @@ namespace Emby.Server.Implementations EncoderLocation = _mediaEncoder.EncoderLocation, SystemArchitecture = RuntimeInformation.OSArchitecture, SystemUpdateLevel = SystemUpdateLevel, - PackageName = StartupOptions.PackageName + PackageName = _startupOptions.PackageName }; } public IEnumerable GetWakeOnLanInfo() - => NetworkManager.GetMacAddresses() + => _networkManager.GetMacAddresses() .Select(i => new WakeOnLanInfo(i)) .ToList(); @@ -1350,7 +1339,7 @@ namespace Emby.Server.Implementations if (addresses.Count == 0) { - addresses.AddRange(NetworkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); + addresses.AddRange(_networkManager.GetLocalIpAddresses(ServerConfigurationManager.Configuration.IgnoreVirtualInterfaces)); } var resultList = new List(); @@ -1594,12 +1583,8 @@ namespace Emby.Server.Implementations Logger.LogError(ex, "Error disposing {Type}", part.GetType().Name); } } - - _userRepository?.Dispose(); } - _userRepository = null; - _disposed = true; } } diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 227f1a5e7e..8db4146cd3 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -42,7 +42,7 @@ namespace Emby.Server.Implementations.Data private readonly IServerConfigurationManager _config; private readonly IServerApplicationHost _appHost; private readonly ILocalizationManager _localization; - // TODO: Remove this dependency + // TODO: Remove this dependency. GetImageCacheTag() is the only method used and it can be converted to a static helper method private readonly IImageProcessor _imageProcessor; private readonly TypeMapper _typeMapper; diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index b35200e757..c3ac2ab411 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -36,9 +36,6 @@ namespace Jellyfin.Server { } - /// - public override bool CanSelfRestart => StartupOptions.RestartPath != null; - /// protected override void RestartInternal() => Program.Restart(); From f2760cb055ae6ee5971ca4a3ff342ecd7d829d99 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 5 Apr 2020 10:03:53 -0400 Subject: [PATCH 101/517] Register IImageEncoder in Jellyfin.Server instead of Emby.Server.Implementations --- Emby.Server.Implementations/ApplicationHost.cs | 8 +------- .../Emby.Server.Implementations.csproj | 1 - Jellyfin.Server/CoreAppHost.cs | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 06b6fec555..0bc47627a1 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -48,7 +48,6 @@ using Emby.Server.Implementations.Session; using Emby.Server.Implementations.SocketSharp; using Emby.Server.Implementations.TV; using Emby.Server.Implementations.Updates; -using Jellyfin.Drawing.Skia; using MediaBrowser.Api; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; @@ -540,13 +539,8 @@ namespace Emby.Server.Implementations /// /// Registers services/resources with the service collection that will be available via DI. /// - protected void RegisterServices(IServiceCollection serviceCollection) + protected virtual void RegisterServices(IServiceCollection serviceCollection) { - var imageEncoderType = SkiaEncoder.IsNativeLibAvailable() - ? typeof(SkiaEncoder) - : typeof(NullImageEncoder); - serviceCollection.AddSingleton(typeof(IImageEncoder), imageEncoderType); - serviceCollection.AddSingleton(_startupOptions); serviceCollection.AddMemoryCache(); diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 6c20842c7f..d302d89843 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -4,7 +4,6 @@ - diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index c3ac2ab411..0769bf844e 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -1,9 +1,12 @@ using System.Collections.Generic; using System.Reflection; +using Emby.Drawing; using Emby.Server.Implementations; +using Jellyfin.Drawing.Skia; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Drawing; using MediaBrowser.Model.IO; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Jellyfin.Server @@ -36,6 +39,17 @@ namespace Jellyfin.Server { } + /// + protected override void RegisterServices(IServiceCollection serviceCollection) + { + var imageEncoderType = SkiaEncoder.IsNativeLibAvailable() + ? typeof(SkiaEncoder) + : typeof(NullImageEncoder); + serviceCollection.AddSingleton(typeof(IImageEncoder), imageEncoderType); + + base.RegisterServices(serviceCollection); + } + /// protected override void RestartInternal() => Program.Restart(); From 30ce346f343ca61f921ec7d6faf2f06311c04e71 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 5 Apr 2020 18:10:56 +0200 Subject: [PATCH 102/517] Enable nullabe reference types for MediaBrowser.Model --- Emby.Dlna/Ssdp/DeviceDiscovery.cs | 16 ++---- .../ServerConfigurationManager.cs | 2 +- .../Cryptography/CryptographyProvider.cs | 4 +- .../Devices/DeviceManager.cs | 16 ++---- .../EntryPoints/UdpServerEntryPoint.cs | 3 +- .../Library/MediaSourceManager.cs | 6 +- .../Library/UserManager.cs | 10 ++-- .../LiveTv/EmbyTV/TimerManager.cs | 4 +- .../LiveTv/LiveTvManager.cs | 57 +++++-------------- .../Playlists/PlaylistManager.cs | 5 +- .../ScheduledTasks/ScheduledTaskWorker.cs | 11 ++-- .../ScheduledTasks/TaskManager.cs | 11 +--- .../Updates/InstallationManager.cs | 2 +- MediaBrowser.Api/EnvironmentService.cs | 15 +---- MediaBrowser.Api/Images/RemoteImageService.cs | 3 +- .../LiveTv/TimerEventInfo.cs | 13 ++++- .../Activity/ActivityLogEntry.cs | 1 + .../ApiClient/ServerDiscoveryInfo.cs | 1 + .../Branding/BrandingOptions.cs | 1 + .../Channels/ChannelFeatures.cs | 1 + MediaBrowser.Model/Channels/ChannelInfo.cs | 1 + MediaBrowser.Model/Channels/ChannelQuery.cs | 6 ++ .../BaseApplicationConfiguration.cs | 1 + .../Configuration/EncodingOptions.cs | 13 +++++ .../Configuration/LibraryOptions.cs | 1 + .../Configuration/MetadataOptions.cs | 4 ++ .../Configuration/MetadataPlugin.cs | 1 + .../Configuration/MetadataPluginSummary.cs | 1 + .../Configuration/ServerConfiguration.cs | 1 + .../Configuration/UserConfiguration.cs | 1 + .../Configuration/XbmcMetadataOptions.cs | 1 + .../Cryptography/ICryptoProvider.cs | 2 +- .../Devices/ContentUploadHistory.cs | 6 +- MediaBrowser.Model/Devices/DeviceInfo.cs | 1 + MediaBrowser.Model/Devices/DevicesOptions.cs | 3 + MediaBrowser.Model/Devices/LocalFileInfo.cs | 4 ++ MediaBrowser.Model/Diagnostics/IProcess.cs | 8 +++ .../Diagnostics/IProcessFactory.cs | 11 ++++ MediaBrowser.Model/Dlna/AudioOptions.cs | 6 ++ MediaBrowser.Model/Dlna/CodecProfile.cs | 1 + MediaBrowser.Model/Dlna/ConditionProcessor.cs | 36 ++---------- MediaBrowser.Model/Dlna/ContainerProfile.cs | 4 +- .../Dlna/ContentFeatureBuilder.cs | 6 +- .../Dlna/DeviceIdentification.cs | 1 + MediaBrowser.Model/Dlna/DeviceProfile.cs | 1 + MediaBrowser.Model/Dlna/DeviceProfileInfo.cs | 1 + MediaBrowser.Model/Dlna/DirectPlayProfile.cs | 1 + MediaBrowser.Model/Dlna/HttpHeaderInfo.cs | 1 + MediaBrowser.Model/Dlna/ITranscoderSupport.cs | 5 ++ .../Dlna/MediaFormatProfileResolver.cs | 24 ++++---- MediaBrowser.Model/Dlna/ProfileCondition.cs | 25 ++++---- .../Dlna/ResolutionConfiguration.cs | 1 + .../Dlna/ResolutionNormalizer.cs | 5 +- MediaBrowser.Model/Dlna/ResolutionOptions.cs | 1 + MediaBrowser.Model/Dlna/ResponseProfile.cs | 4 +- MediaBrowser.Model/Dlna/SearchCriteria.cs | 9 ++- MediaBrowser.Model/Dlna/StreamBuilder.cs | 2 + MediaBrowser.Model/Dlna/StreamInfo.cs | 1 + MediaBrowser.Model/Dlna/SubtitleProfile.cs | 1 + MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs | 9 +++ MediaBrowser.Model/Dlna/TranscodingProfile.cs | 1 + MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs | 4 ++ MediaBrowser.Model/Dlna/VideoOptions.cs | 1 + MediaBrowser.Model/Dlna/XmlAttribute.cs | 1 + MediaBrowser.Model/Drawing/DrawingUtils.cs | 5 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 1 + MediaBrowser.Model/Dto/BaseItemPerson.cs | 1 + MediaBrowser.Model/Dto/IHasServerId.cs | 1 + MediaBrowser.Model/Dto/ImageByNameInfo.cs | 1 + MediaBrowser.Model/Dto/ImageInfo.cs | 5 +- MediaBrowser.Model/Dto/ImageOptions.cs | 17 +++--- MediaBrowser.Model/Dto/ItemIndex.cs | 20 ------- MediaBrowser.Model/Dto/MediaSourceInfo.cs | 1 + MediaBrowser.Model/Dto/MetadataEditorInfo.cs | 1 + MediaBrowser.Model/Dto/NameIdPair.cs | 1 + MediaBrowser.Model/Dto/NameValuePair.cs | 2 +- MediaBrowser.Model/Dto/RecommendationDto.cs | 1 + MediaBrowser.Model/Dto/UserDto.cs | 1 + MediaBrowser.Model/Dto/UserItemDataDto.cs | 1 + MediaBrowser.Model/Entities/ChapterInfo.cs | 1 + .../Entities/DisplayPreferences.cs | 1 + .../Entities/IHasProviderIds.cs | 2 +- .../Entities/LibraryUpdateInfo.cs | 29 +++++----- .../Entities/MediaAttachment.cs | 1 + MediaBrowser.Model/Entities/MediaStream.cs | 1 + MediaBrowser.Model/Entities/MediaUrl.cs | 1 + .../Entities/PackageReviewInfo.cs | 13 +++-- MediaBrowser.Model/Entities/ParentalRating.cs | 24 ++++---- .../Entities/ProviderIdsExtensions.cs | 12 ++-- .../Entities/VirtualFolderInfo.cs | 1 + MediaBrowser.Model/Events/GenericEventArgs.cs | 7 --- MediaBrowser.Model/Extensions/ListHelper.cs | 2 + MediaBrowser.Model/Extensions/StringHelper.cs | 4 +- .../Globalization/CountryInfo.cs | 1 + .../Globalization/CultureDto.cs | 1 + .../Globalization/ILocalizationManager.cs | 1 + .../Globalization/LocalizationOption.cs | 2 + MediaBrowser.Model/IO/FileSystemEntryInfo.cs | 27 ++++++--- MediaBrowser.Model/IO/FileSystemMetadata.cs | 1 + MediaBrowser.Model/IO/IFileSystem.cs | 1 + MediaBrowser.Model/IO/IIsoManager.cs | 1 - MediaBrowser.Model/IO/IIsoMount.cs | 2 +- MediaBrowser.Model/IO/IIsoMounter.cs | 12 ++-- MediaBrowser.Model/IO/IStreamHelper.cs | 1 + MediaBrowser.Model/Library/UserViewQuery.cs | 12 ++-- MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs | 1 + MediaBrowser.Model/LiveTv/GuideInfo.cs | 1 + .../LiveTv/LiveTvChannelQuery.cs | 1 + MediaBrowser.Model/LiveTv/LiveTvInfo.cs | 12 ++-- MediaBrowser.Model/LiveTv/LiveTvOptions.cs | 1 + .../LiveTv/LiveTvServiceInfo.cs | 1 + MediaBrowser.Model/LiveTv/RecordingQuery.cs | 1 + .../LiveTv/SeriesTimerInfoDto.cs | 3 +- MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs | 2 +- MediaBrowser.Model/LiveTv/TimerInfoDto.cs | 1 + MediaBrowser.Model/LiveTv/TimerQuery.cs | 1 + MediaBrowser.Model/MediaBrowser.Model.csproj | 2 + MediaBrowser.Model/MediaInfo/AudioCodec.cs | 4 +- .../MediaInfo/BlurayDiscInfo.cs | 1 + .../MediaInfo/LiveStreamRequest.cs | 18 +++--- .../MediaInfo/LiveStreamResponse.cs | 7 ++- MediaBrowser.Model/MediaInfo/MediaInfo.cs | 1 + .../MediaInfo/PlaybackInfoRequest.cs | 1 + .../MediaInfo/PlaybackInfoResponse.cs | 2 +- .../MediaInfo/SubtitleTrackEvent.cs | 4 ++ MediaBrowser.Model/Net/EndPointInfo.cs | 1 + MediaBrowser.Model/Net/ISocket.cs | 1 + MediaBrowser.Model/Net/MimeTypes.cs | 18 +++--- MediaBrowser.Model/Net/NetworkShare.cs | 1 + MediaBrowser.Model/Net/SocketReceiveResult.cs | 10 +++- MediaBrowser.Model/Net/WebSocketMessage.cs | 1 + .../Notifications/NotificationOption.cs | 16 +++--- .../Notifications/NotificationOptions.cs | 37 ++++++------ .../Notifications/NotificationRequest.cs | 1 + .../Notifications/NotificationTypeInfo.cs | 1 + .../Playlists/PlaylistCreationRequest.cs | 1 + .../Playlists/PlaylistCreationResult.cs | 7 ++- .../Playlists/PlaylistItemQuery.cs | 39 ------------- MediaBrowser.Model/Plugins/PluginInfo.cs | 1 + MediaBrowser.Model/Plugins/PluginPageInfo.cs | 1 + .../Providers/ExternalIdInfo.cs | 1 + MediaBrowser.Model/Providers/ExternalUrl.cs | 1 + .../Providers/ImageProviderInfo.cs | 11 ++-- .../Providers/RemoteImageInfo.cs | 1 + .../Providers/RemoteImageQuery.cs | 7 ++- .../Providers/RemoteImageResult.cs | 1 + .../Providers/RemoteSearchResult.cs | 20 +++++-- .../Providers/RemoteSubtitleInfo.cs | 1 + .../Providers/SubtitleOptions.cs | 1 + .../Providers/SubtitleProviderInfo.cs | 1 + .../Querying/AllThemeMediaResult.cs | 13 +++-- MediaBrowser.Model/Querying/EpisodeQuery.cs | 1 + .../Querying/ItemCountsQuery.cs | 20 ------- MediaBrowser.Model/Querying/ItemSortBy.cs | 54 +++++++++++++----- .../Querying/LatestItemsQuery.cs | 20 ++++--- .../Querying/MovieRecommendationQuery.cs | 1 + MediaBrowser.Model/Querying/NextUpQuery.cs | 1 + MediaBrowser.Model/Querying/QueryFilters.cs | 1 + MediaBrowser.Model/Querying/QueryResult.cs | 1 + .../Querying/ThemeMediaResult.cs | 2 +- .../Querying/UpcomingEpisodesQuery.cs | 1 + MediaBrowser.Model/Search/SearchHint.cs | 1 + MediaBrowser.Model/Search/SearchHintResult.cs | 1 + MediaBrowser.Model/Search/SearchQuery.cs | 1 + .../Serialization/IJsonSerializer.cs | 1 + .../Serialization/IXmlSerializer.cs | 1 + .../Services/ApiMemberAttribute.cs | 1 + .../Services/IHasRequestFilter.cs | 10 ++-- MediaBrowser.Model/Services/IHttpRequest.cs | 4 +- MediaBrowser.Model/Services/IHttpResult.cs | 11 ++-- MediaBrowser.Model/Services/IRequest.cs | 1 + .../Services/QueryParamCollection.cs | 6 +- MediaBrowser.Model/Services/RouteAttribute.cs | 1 + MediaBrowser.Model/Session/BrowseRequest.cs | 1 + .../Session/ClientCapabilities.cs | 1 + MediaBrowser.Model/Session/GeneralCommand.cs | 1 + MediaBrowser.Model/Session/MessageCommand.cs | 1 + MediaBrowser.Model/Session/PlayRequest.cs | 1 + .../Session/PlaybackProgressInfo.cs | 1 + .../Session/PlaybackStopInfo.cs | 1 + MediaBrowser.Model/Session/PlayerStateInfo.cs | 1 + .../Session/PlaystateRequest.cs | 2 +- MediaBrowser.Model/Session/SessionUserInfo.cs | 2 + MediaBrowser.Model/Session/TranscodingInfo.cs | 5 +- .../Session/UserDataChangeInfo.cs | 1 + MediaBrowser.Model/Sync/SyncJob.cs | 1 + MediaBrowser.Model/Sync/SyncTarget.cs | 1 + MediaBrowser.Model/System/LogFile.cs | 1 + MediaBrowser.Model/System/PublicSystemInfo.cs | 1 + MediaBrowser.Model/System/SystemInfo.cs | 2 +- MediaBrowser.Model/System/WakeOnLanInfo.cs | 31 +++++----- MediaBrowser.Model/Tasks/IScheduledTask.cs | 11 ++-- .../Tasks/IScheduledTaskWorker.cs | 1 + .../Tasks/ScheduledTaskHelpers.cs | 4 +- .../Tasks/TaskCompletionEventArgs.cs | 10 +++- MediaBrowser.Model/Tasks/TaskInfo.cs | 1 + MediaBrowser.Model/Tasks/TaskResult.cs | 1 + MediaBrowser.Model/Tasks/TaskTriggerInfo.cs | 1 + .../Updates/CheckForUpdateResult.cs | 1 + .../Updates/InstallationInfo.cs | 1 + MediaBrowser.Model/Updates/PackageInfo.cs | 1 + .../Updates/PackageVersionInfo.cs | 1 + .../Users/ForgotPasswordResult.cs | 1 + MediaBrowser.Model/Users/PinRedeemResult.cs | 1 + MediaBrowser.Model/Users/UserAction.cs | 1 + MediaBrowser.Model/Users/UserPolicy.cs | 1 + .../Manager/ItemImageProvider.cs | 24 +++++--- .../Manager/ProviderManager.cs | 6 +- 208 files changed, 636 insertions(+), 506 deletions(-) delete mode 100644 MediaBrowser.Model/Dto/ItemIndex.cs delete mode 100644 MediaBrowser.Model/Playlists/PlaylistItemQuery.cs delete mode 100644 MediaBrowser.Model/Querying/ItemCountsQuery.cs diff --git a/Emby.Dlna/Ssdp/DeviceDiscovery.cs b/Emby.Dlna/Ssdp/DeviceDiscovery.cs index f95b8ce7de..ab5e56ab07 100644 --- a/Emby.Dlna/Ssdp/DeviceDiscovery.cs +++ b/Emby.Dlna/Ssdp/DeviceDiscovery.cs @@ -100,15 +100,13 @@ namespace Emby.Dlna.Ssdp var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase); - var args = new GenericEventArgs - { - Argument = new UpnpDeviceInfo + var args = new GenericEventArgs( + new UpnpDeviceInfo { Location = e.DiscoveredDevice.DescriptionLocation, Headers = headers, LocalIpAddress = e.LocalIpAddress - } - }; + }); DeviceDiscoveredInternal?.Invoke(this, args); } @@ -121,14 +119,12 @@ namespace Emby.Dlna.Ssdp var headers = headerDict.ToDictionary(i => i.Key, i => i.Value.Value.FirstOrDefault(), StringComparer.OrdinalIgnoreCase); - var args = new GenericEventArgs - { - Argument = new UpnpDeviceInfo + var args = new GenericEventArgs( + new UpnpDeviceInfo { Location = e.DiscoveredDevice.DescriptionLocation, Headers = headers - } - }; + }); DeviceLeft?.Invoke(this, args); } diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs index f407317ec7..5062683a17 100644 --- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -91,7 +91,7 @@ namespace Emby.Server.Implementations.Configuration ValidateMetadataPath(newConfig); ValidateSslCertificate(newConfig); - ConfigurationUpdating?.Invoke(this, new GenericEventArgs { Argument = newConfig }); + ConfigurationUpdating?.Invoke(this, new GenericEventArgs(newConfig)); base.ReplaceConfiguration(newConfiguration); } diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index de83b023d7..1e42dbf675 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; using System.Security.Cryptography; @@ -134,8 +136,6 @@ namespace Emby.Server.Implementations.Cryptography _randomNumberGenerator.Dispose(); } - _randomNumberGenerator = null; - _disposed = true; } } diff --git a/Emby.Server.Implementations/Devices/DeviceManager.cs b/Emby.Server.Implementations/Devices/DeviceManager.cs index adb8e793d2..e8837892cc 100644 --- a/Emby.Server.Implementations/Devices/DeviceManager.cs +++ b/Emby.Server.Implementations/Devices/DeviceManager.cs @@ -86,13 +86,7 @@ namespace Emby.Server.Implementations.Devices { _authRepo.UpdateDeviceOptions(deviceId, options); - if (DeviceOptionsUpdated != null) - { - DeviceOptionsUpdated(this, new GenericEventArgs>() - { - Argument = new Tuple(deviceId, options) - }); - } + DeviceOptionsUpdated?.Invoke(this, new GenericEventArgs>(new Tuple(deviceId, options))); } public DeviceOptions GetDeviceOptions(string deviceId) @@ -251,14 +245,12 @@ namespace Emby.Server.Implementations.Devices if (CameraImageUploaded != null) { - CameraImageUploaded?.Invoke(this, new GenericEventArgs - { - Argument = new CameraImageUploadInfo + CameraImageUploaded?.Invoke(this, new GenericEventArgs( + new CameraImageUploadInfo { Device = device, FileInfo = file - } - }); + })); } } diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index 50ba0f8fac..fa566d24b6 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -44,10 +44,11 @@ namespace Emby.Server.Implementations.EntryPoints } /// - public async Task RunAsync() + public Task RunAsync() { _udpServer = new UdpServer(_logger, _appHost); _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + return Task.CompletedTask; } /// diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs index 70d5bd9f4e..4f12ad0467 100644 --- a/Emby.Server.Implementations/Library/MediaSourceManager.cs +++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs @@ -521,11 +521,7 @@ namespace Emby.Server.Implementations.Library SetDefaultAudioAndSubtitleStreamIndexes(item, clone, user); } - return new Tuple(new LiveStreamResponse - { - MediaSource = clone - - }, liveStream as IDirectStreamProvider); + return new Tuple(new LiveStreamResponse(clone), liveStream as IDirectStreamProvider); } private static void AddMediaInfo(MediaSourceInfo mediaSource, bool isAudio) diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 7b17cc913f..614ab5669e 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -131,7 +131,7 @@ namespace Emby.Server.Implementations.Library /// The user. private void OnUserUpdated(User user) { - UserUpdated?.Invoke(this, new GenericEventArgs { Argument = user }); + UserUpdated?.Invoke(this, new GenericEventArgs(user)); } /// @@ -140,7 +140,7 @@ namespace Emby.Server.Implementations.Library /// The user. private void OnUserDeleted(User user) { - UserDeleted?.Invoke(this, new GenericEventArgs { Argument = user }); + UserDeleted?.Invoke(this, new GenericEventArgs(user)); } public NameIdPair[] GetAuthenticationProviders() @@ -755,7 +755,7 @@ namespace Emby.Server.Implementations.Library _userRepository.CreateUser(user); - EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs { Argument = user }, _logger); + EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs(user), _logger); return user; } @@ -980,7 +980,7 @@ namespace Emby.Server.Implementations.Library if (fireEvent) { - UserPolicyUpdated?.Invoke(this, new GenericEventArgs { Argument = user }); + UserPolicyUpdated?.Invoke(this, new GenericEventArgs(user)); } } @@ -1050,7 +1050,7 @@ namespace Emby.Server.Implementations.Library if (fireEvent) { - UserConfigurationUpdated?.Invoke(this, new GenericEventArgs { Argument = user }); + UserConfigurationUpdated?.Invoke(this, new GenericEventArgs(user)); } } } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs index 7ebb043d8e..285a59a249 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/TimerManager.cs @@ -109,7 +109,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV if (startDate < now) { - TimerFired?.Invoke(this, new GenericEventArgs { Argument = item }); + TimerFired?.Invoke(this, new GenericEventArgs(item)); return; } @@ -151,7 +151,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var timer = GetAll().FirstOrDefault(i => string.Equals(i.Id, timerId, StringComparison.OrdinalIgnoreCase)); if (timer != null) { - TimerFired?.Invoke(this, new GenericEventArgs { Argument = timer }); + TimerFired?.Invoke(this, new GenericEventArgs(timer)); } } diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs index b64fe8634c..16c659532a 100644 --- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs +++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs @@ -149,27 +149,18 @@ namespace Emby.Server.Implementations.LiveTv { var timerId = e.Argument; - TimerCancelled?.Invoke(this, new GenericEventArgs - { - Argument = new TimerEventInfo - { - Id = timerId - } - }); + TimerCancelled?.Invoke(this, new GenericEventArgs(new TimerEventInfo(timerId))); } private void OnEmbyTvTimerCreated(object sender, GenericEventArgs e) { var timer = e.Argument; - TimerCreated?.Invoke(this, new GenericEventArgs - { - Argument = new TimerEventInfo + TimerCreated?.Invoke(this, new GenericEventArgs( + new TimerEventInfo(timer.Id) { - ProgramId = _tvDtoService.GetInternalProgramId(timer.ProgramId), - Id = timer.Id - } - }); + ProgramId = _tvDtoService.GetInternalProgramId(timer.ProgramId) + })); } public List GetTunerHostTypes() @@ -1725,13 +1716,7 @@ namespace Emby.Server.Implementations.LiveTv if (!(service is EmbyTV.EmbyTV)) { - TimerCancelled?.Invoke(this, new GenericEventArgs - { - Argument = new TimerEventInfo - { - Id = id - } - }); + TimerCancelled?.Invoke(this, new GenericEventArgs(new TimerEventInfo(id))); } } @@ -1748,13 +1733,7 @@ namespace Emby.Server.Implementations.LiveTv await service.CancelSeriesTimerAsync(timer.ExternalId, CancellationToken.None).ConfigureAwait(false); - SeriesTimerCancelled?.Invoke(this, new GenericEventArgs - { - Argument = new TimerEventInfo - { - Id = id - } - }); + SeriesTimerCancelled?.Invoke(this, new GenericEventArgs(new TimerEventInfo(id))); } public async Task GetTimer(string id, CancellationToken cancellationToken) @@ -2073,14 +2052,11 @@ namespace Emby.Server.Implementations.LiveTv if (!(service is EmbyTV.EmbyTV)) { - TimerCreated?.Invoke(this, new GenericEventArgs - { - Argument = new TimerEventInfo + TimerCreated?.Invoke(this, new GenericEventArgs( + new TimerEventInfo(newTimerId) { - ProgramId = _tvDtoService.GetInternalProgramId(info.ProgramId), - Id = newTimerId - } - }); + ProgramId = _tvDtoService.GetInternalProgramId(info.ProgramId) + })); } } @@ -2105,14 +2081,11 @@ namespace Emby.Server.Implementations.LiveTv await service.CreateSeriesTimerAsync(info, cancellationToken).ConfigureAwait(false); } - SeriesTimerCreated?.Invoke(this, new GenericEventArgs - { - Argument = new TimerEventInfo + SeriesTimerCreated?.Invoke(this, new GenericEventArgs( + new TimerEventInfo(newTimerId) { - ProgramId = _tvDtoService.GetInternalProgramId(info.ProgramId), - Id = newTimerId - } - }); + ProgramId = _tvDtoService.GetInternalProgramId(info.ProgramId) + })); } public async Task UpdateTimer(TimerInfoDto timer, CancellationToken cancellationToken) diff --git a/Emby.Server.Implementations/Playlists/PlaylistManager.cs b/Emby.Server.Implementations/Playlists/PlaylistManager.cs index 9b1510ac97..021bc47cda 100644 --- a/Emby.Server.Implementations/Playlists/PlaylistManager.cs +++ b/Emby.Server.Implementations/Playlists/PlaylistManager.cs @@ -153,10 +153,7 @@ namespace Emby.Server.Implementations.Playlists }); } - return new PlaylistCreationResult - { - Id = playlist.Id.ToString("N", CultureInfo.InvariantCulture) - }; + return new PlaylistCreationResult(playlist.Id.ToString("N", CultureInfo.InvariantCulture)); } finally { diff --git a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs index 5b188d9626..ca983764b2 100644 --- a/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs +++ b/Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs @@ -392,7 +392,7 @@ namespace Emby.Server.Implementations.ScheduledTasks ((TaskManager)TaskManager).OnTaskExecuting(this); - progress.ProgressChanged += progress_ProgressChanged; + progress.ProgressChanged += OnProgressChanged; TaskCompletionStatus status; CurrentExecutionStartTime = DateTime.UtcNow; @@ -426,7 +426,7 @@ namespace Emby.Server.Implementations.ScheduledTasks var startTime = CurrentExecutionStartTime; var endTime = DateTime.UtcNow; - progress.ProgressChanged -= progress_ProgressChanged; + progress.ProgressChanged -= OnProgressChanged; CurrentCancellationTokenSource.Dispose(); CurrentCancellationTokenSource = null; CurrentProgress = null; @@ -439,16 +439,13 @@ namespace Emby.Server.Implementations.ScheduledTasks /// /// The sender. /// The e. - void progress_ProgressChanged(object sender, double e) + private void OnProgressChanged(object sender, double e) { e = Math.Min(e, 100); CurrentProgress = e; - TaskProgress?.Invoke(this, new GenericEventArgs - { - Argument = e - }); + TaskProgress?.Invoke(this, new GenericEventArgs(e)); } /// diff --git a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs index ecf58dbc0e..f2e04d1fb4 100644 --- a/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs +++ b/Emby.Server.Implementations/ScheduledTasks/TaskManager.cs @@ -254,10 +254,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// The task. internal void OnTaskExecuting(IScheduledTaskWorker task) { - TaskExecuting?.Invoke(this, new GenericEventArgs - { - Argument = task - }); + TaskExecuting?.Invoke(this, new GenericEventArgs(task)); } /// @@ -267,11 +264,7 @@ namespace Emby.Server.Implementations.ScheduledTasks /// The result. internal void OnTaskCompleted(IScheduledTaskWorker task, TaskResult result) { - TaskCompleted?.Invoke(task, new TaskCompletionEventArgs - { - Result = result, - Task = task - }); + TaskCompleted?.Invoke(task, new TaskCompletionEventArgs(task, result)); ExecuteQueuedTasks(); } diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index c897036eb8..51563fd5d4 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -427,7 +427,7 @@ namespace Emby.Server.Implementations.Updates _config.SaveConfiguration(); } - PluginUninstalled?.Invoke(this, new GenericEventArgs { Argument = plugin }); + PluginUninstalled?.Invoke(this, new GenericEventArgs(plugin)); _applicationHost.NotifyPendingRestart(); } diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs index 36b03f09ce..10726e2aaf 100644 --- a/MediaBrowser.Api/EnvironmentService.cs +++ b/MediaBrowser.Api/EnvironmentService.cs @@ -226,12 +226,7 @@ namespace MediaBrowser.Api /// IEnumerable{FileSystemEntryInfo}. private IEnumerable GetDrives() { - return _fileSystem.GetDrives().Select(d => new FileSystemEntryInfo - { - Name = d.Name, - Path = d.FullName, - Type = FileSystemEntryType.Directory - }); + return _fileSystem.GetDrives().Select(d => new FileSystemEntryInfo(d.Name, d.FullName, FileSystemEntryType.Directory)); } /// @@ -266,13 +261,7 @@ namespace MediaBrowser.Api return true; }); - return entries.Select(f => new FileSystemEntryInfo - { - Name = f.Name, - Path = f.FullName, - Type = f.IsDirectory ? FileSystemEntryType.Directory : FileSystemEntryType.File - - }); + return entries.Select(f => new FileSystemEntryInfo(f.Name, f.FullName, f.IsDirectory ? FileSystemEntryType.Directory : FileSystemEntryType.File)); } public object Get(GetParentPath request) diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index f03f5efd8d..3e4198aae6 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -147,9 +147,8 @@ namespace MediaBrowser.Api.Images { var item = _libraryManager.GetItemById(request.Id); - var images = await _providerManager.GetAvailableRemoteImages(item, new RemoteImageQuery + var images = await _providerManager.GetAvailableRemoteImages(item, new RemoteImageQuery(request.ProviderName) { - ProviderName = request.ProviderName, IncludeAllLanguages = request.IncludeAllLanguages, IncludeDisabledProviders = true, ImageType = request.Type diff --git a/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs index cfec39b4e9..1b8f41db69 100644 --- a/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs +++ b/MediaBrowser.Controller/LiveTv/TimerEventInfo.cs @@ -1,10 +1,19 @@ +#nullable enable +#pragma warning disable CS1591 + using System; namespace MediaBrowser.Controller.LiveTv { public class TimerEventInfo { - public string Id { get; set; } - public Guid ProgramId { get; set; } + public TimerEventInfo(string id) + { + Id = id; + } + + public string Id { get; } + + public Guid? ProgramId { get; set; } } } diff --git a/MediaBrowser.Model/Activity/ActivityLogEntry.cs b/MediaBrowser.Model/Activity/ActivityLogEntry.cs index 80f01b66ee..865d07b2c4 100644 --- a/MediaBrowser.Model/Activity/ActivityLogEntry.cs +++ b/MediaBrowser.Model/Activity/ActivityLogEntry.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs b/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs index bb203f8958..fcc90a1f7a 100644 --- a/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs +++ b/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.ApiClient diff --git a/MediaBrowser.Model/Branding/BrandingOptions.cs b/MediaBrowser.Model/Branding/BrandingOptions.cs index 8ab268a64d..5ddf1e7e6e 100644 --- a/MediaBrowser.Model/Branding/BrandingOptions.cs +++ b/MediaBrowser.Model/Branding/BrandingOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Branding diff --git a/MediaBrowser.Model/Channels/ChannelFeatures.cs b/MediaBrowser.Model/Channels/ChannelFeatures.cs index c4e97ffe59..496102d83b 100644 --- a/MediaBrowser.Model/Channels/ChannelFeatures.cs +++ b/MediaBrowser.Model/Channels/ChannelFeatures.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Channels/ChannelInfo.cs b/MediaBrowser.Model/Channels/ChannelInfo.cs index bfb34db559..f2432aaeb2 100644 --- a/MediaBrowser.Model/Channels/ChannelInfo.cs +++ b/MediaBrowser.Model/Channels/ChannelInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Channels diff --git a/MediaBrowser.Model/Channels/ChannelQuery.cs b/MediaBrowser.Model/Channels/ChannelQuery.cs index 88fc94a6fc..d112600390 100644 --- a/MediaBrowser.Model/Channels/ChannelQuery.cs +++ b/MediaBrowser.Model/Channels/ChannelQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -13,8 +14,11 @@ namespace MediaBrowser.Model.Channels /// /// The fields. public ItemFields[] Fields { get; set; } + public bool? EnableImages { get; set; } + public int? ImageTypeLimit { get; set; } + public ImageType[] EnableImageTypes { get; set; } /// @@ -48,7 +52,9 @@ namespace MediaBrowser.Model.Channels /// /// null if [is favorite] contains no value, true if [is favorite]; otherwise, false. public bool? IsFavorite { get; set; } + public bool? IsRecordingsFolder { get; set; } + public bool RefreshLatestChannelItems { get; set; } } } diff --git a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs index cc2541f74f..cdd322c948 100644 --- a/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs +++ b/MediaBrowser.Model/Configuration/BaseApplicationConfiguration.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Xml.Serialization; diff --git a/MediaBrowser.Model/Configuration/EncodingOptions.cs b/MediaBrowser.Model/Configuration/EncodingOptions.cs index 648568fd70..0c0e01f111 100644 --- a/MediaBrowser.Model/Configuration/EncodingOptions.cs +++ b/MediaBrowser.Model/Configuration/EncodingOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Configuration @@ -5,10 +6,15 @@ namespace MediaBrowser.Model.Configuration public class EncodingOptions { public int EncodingThreadCount { get; set; } + public string TranscodingTempPath { get; set; } + public double DownMixAudioBoost { get; set; } + public bool EnableThrottling { get; set; } + public int ThrottleDelaySeconds { get; set; } + public string HardwareAccelerationType { get; set; } /// @@ -20,12 +26,19 @@ namespace MediaBrowser.Model.Configuration /// The current FFmpeg path being used by the system and displayed on the transcode page. /// public string EncoderAppPathDisplay { get; set; } + public string VaapiDevice { get; set; } + public int H264Crf { get; set; } + public int H265Crf { get; set; } + public string EncoderPreset { get; set; } + public string DeinterlaceMethod { get; set; } + public bool EnableHardwareEncoding { get; set; } + public bool EnableSubtitleExtraction { get; set; } public string[] HardwareDecodingCodecs { get; set; } diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs index 4342ccd8ae..4229a4335b 100644 --- a/MediaBrowser.Model/Configuration/LibraryOptions.cs +++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Configuration/MetadataOptions.cs b/MediaBrowser.Model/Configuration/MetadataOptions.cs index 625054b9e4..e7dc3da3cb 100644 --- a/MediaBrowser.Model/Configuration/MetadataOptions.cs +++ b/MediaBrowser.Model/Configuration/MetadataOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -12,12 +13,15 @@ namespace MediaBrowser.Model.Configuration public string ItemType { get; set; } public string[] DisabledMetadataSavers { get; set; } + public string[] LocalMetadataReaderOrder { get; set; } public string[] DisabledMetadataFetchers { get; set; } + public string[] MetadataFetcherOrder { get; set; } public string[] DisabledImageFetchers { get; set; } + public string[] ImageFetcherOrder { get; set; } public MetadataOptions() diff --git a/MediaBrowser.Model/Configuration/MetadataPlugin.cs b/MediaBrowser.Model/Configuration/MetadataPlugin.cs index c2b47eb9bd..db8cd1875d 100644 --- a/MediaBrowser.Model/Configuration/MetadataPlugin.cs +++ b/MediaBrowser.Model/Configuration/MetadataPlugin.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Configuration diff --git a/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs b/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs index 53063810b9..0c197ee021 100644 --- a/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs +++ b/MediaBrowser.Model/Configuration/MetadataPluginSummary.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 3107ec2426..333805e316 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Configuration/UserConfiguration.cs b/MediaBrowser.Model/Configuration/UserConfiguration.cs index a475c9910b..289047d6b4 100644 --- a/MediaBrowser.Model/Configuration/UserConfiguration.cs +++ b/MediaBrowser.Model/Configuration/UserConfiguration.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs b/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs index d6c1295f44..c48a381928 100644 --- a/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs +++ b/MediaBrowser.Model/Configuration/XbmcMetadataOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Configuration diff --git a/MediaBrowser.Model/Cryptography/ICryptoProvider.cs b/MediaBrowser.Model/Cryptography/ICryptoProvider.cs index 656c04f463..d8b7d848a2 100644 --- a/MediaBrowser.Model/Cryptography/ICryptoProvider.cs +++ b/MediaBrowser.Model/Cryptography/ICryptoProvider.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Model.Cryptography IEnumerable GetSupportedHashMethods(); - byte[] ComputeHash(string HashMethod, byte[] bytes, byte[] salt); + byte[] ComputeHash(string hashMethod, byte[] bytes, byte[] salt); byte[] ComputeHashWithDefaultMethod(byte[] bytes, byte[] salt); diff --git a/MediaBrowser.Model/Devices/ContentUploadHistory.cs b/MediaBrowser.Model/Devices/ContentUploadHistory.cs index c493760d51..868956df2b 100644 --- a/MediaBrowser.Model/Devices/ContentUploadHistory.cs +++ b/MediaBrowser.Model/Devices/ContentUploadHistory.cs @@ -1,15 +1,19 @@ +#nullable disable #pragma warning disable CS1591 +using System; + namespace MediaBrowser.Model.Devices { public class ContentUploadHistory { public string DeviceId { get; set; } + public LocalFileInfo[] FilesUploaded { get; set; } public ContentUploadHistory() { - FilesUploaded = new LocalFileInfo[] { }; + FilesUploaded = Array.Empty(); } } } diff --git a/MediaBrowser.Model/Devices/DeviceInfo.cs b/MediaBrowser.Model/Devices/DeviceInfo.cs index d2563d1d0f..0cccf931c4 100644 --- a/MediaBrowser.Model/Devices/DeviceInfo.cs +++ b/MediaBrowser.Model/Devices/DeviceInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Devices/DevicesOptions.cs b/MediaBrowser.Model/Devices/DevicesOptions.cs index 02570650e9..327b5836f7 100644 --- a/MediaBrowser.Model/Devices/DevicesOptions.cs +++ b/MediaBrowser.Model/Devices/DevicesOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -7,7 +8,9 @@ namespace MediaBrowser.Model.Devices public class DevicesOptions { public string[] EnabledCameraUploadDevices { get; set; } + public string CameraUploadPath { get; set; } + public bool EnableCameraUploadSubfolders { get; set; } public DevicesOptions() diff --git a/MediaBrowser.Model/Devices/LocalFileInfo.cs b/MediaBrowser.Model/Devices/LocalFileInfo.cs index 63a8dc2aa5..c3158b2f2e 100644 --- a/MediaBrowser.Model/Devices/LocalFileInfo.cs +++ b/MediaBrowser.Model/Devices/LocalFileInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Devices @@ -5,8 +6,11 @@ namespace MediaBrowser.Model.Devices public class LocalFileInfo { public string Name { get; set; } + public string Id { get; set; } + public string Album { get; set; } + public string MimeType { get; set; } } } diff --git a/MediaBrowser.Model/Diagnostics/IProcess.cs b/MediaBrowser.Model/Diagnostics/IProcess.cs index 514d1e7379..c067189a63 100644 --- a/MediaBrowser.Model/Diagnostics/IProcess.cs +++ b/MediaBrowser.Model/Diagnostics/IProcess.cs @@ -11,13 +11,21 @@ namespace MediaBrowser.Model.Diagnostics event EventHandler Exited; void Kill(); + bool WaitForExit(int timeMs); + Task WaitForExitAsync(int timeMs); + int ExitCode { get; } + void Start(); + StreamWriter StandardInput { get; } + StreamReader StandardError { get; } + StreamReader StandardOutput { get; } + ProcessOptions StartInfo { get; } } } diff --git a/MediaBrowser.Model/Diagnostics/IProcessFactory.cs b/MediaBrowser.Model/Diagnostics/IProcessFactory.cs index 57082acc57..2d15aed7e6 100644 --- a/MediaBrowser.Model/Diagnostics/IProcessFactory.cs +++ b/MediaBrowser.Model/Diagnostics/IProcessFactory.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Diagnostics @@ -10,15 +11,25 @@ namespace MediaBrowser.Model.Diagnostics public class ProcessOptions { public string FileName { get; set; } + public string Arguments { get; set; } + public string WorkingDirectory { get; set; } + public bool CreateNoWindow { get; set; } + public bool UseShellExecute { get; set; } + public bool EnableRaisingEvents { get; set; } + public bool ErrorDialog { get; set; } + public bool RedirectStandardError { get; set; } + public bool RedirectStandardInput { get; set; } + public bool RedirectStandardOutput { get; set; } + public bool IsHidden { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/AudioOptions.cs b/MediaBrowser.Model/Dlna/AudioOptions.cs index 40081b2824..fc555c5f70 100644 --- a/MediaBrowser.Model/Dlna/AudioOptions.cs +++ b/MediaBrowser.Model/Dlna/AudioOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -19,12 +20,17 @@ namespace MediaBrowser.Model.Dlna } public bool EnableDirectPlay { get; set; } + public bool EnableDirectStream { get; set; } + public bool ForceDirectPlay { get; set; } + public bool ForceDirectStream { get; set; } public Guid ItemId { get; set; } + public MediaSourceInfo[] MediaSources { get; set; } + public DeviceProfile Profile { get; set; } /// diff --git a/MediaBrowser.Model/Dlna/CodecProfile.cs b/MediaBrowser.Model/Dlna/CodecProfile.cs index 756e500dd7..cc5b840c76 100644 --- a/MediaBrowser.Model/Dlna/CodecProfile.cs +++ b/MediaBrowser.Model/Dlna/CodecProfile.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dlna/ConditionProcessor.cs b/MediaBrowser.Model/Dlna/ConditionProcessor.cs index 7423efaf65..f3aaef9307 100644 --- a/MediaBrowser.Model/Dlna/ConditionProcessor.cs +++ b/MediaBrowser.Model/Dlna/ConditionProcessor.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Model.Dlna int? height, int? videoBitDepth, int? videoBitrate, - string videoProfile, + string? videoProfile, double? videoLevel, float? videoFramerate, int? packetLength, @@ -25,7 +25,7 @@ namespace MediaBrowser.Model.Dlna int? refFrames, int? numVideoStreams, int? numAudioStreams, - string videoCodecTag, + string? videoCodecTag, bool? isAvc) { switch (condition.Property) @@ -103,7 +103,7 @@ namespace MediaBrowser.Model.Dlna int? audioBitrate, int? audioSampleRate, int? audioBitDepth, - string audioProfile, + string? audioProfile, bool? isSecondaryTrack) { switch (condition.Property) @@ -154,7 +154,7 @@ namespace MediaBrowser.Model.Dlna return false; } - private static bool IsConditionSatisfied(ProfileCondition condition, string currentValue) + private static bool IsConditionSatisfied(ProfileCondition condition, string? currentValue) { if (string.IsNullOrEmpty(currentValue)) { @@ -203,34 +203,6 @@ namespace MediaBrowser.Model.Dlna return false; } - private static bool IsConditionSatisfied(ProfileCondition condition, float currentValue) - { - if (currentValue <= 0) - { - // If the value is unknown, it satisfies if not marked as required - return !condition.IsRequired; - } - - if (float.TryParse(condition.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out var expected)) - { - switch (condition.Condition) - { - case ProfileConditionType.Equals: - return currentValue.Equals(expected); - case ProfileConditionType.GreaterThanEqual: - return currentValue >= expected; - case ProfileConditionType.LessThanEqual: - return currentValue <= expected; - case ProfileConditionType.NotEquals: - return !currentValue.Equals(expected); - default: - throw new InvalidOperationException("Unexpected ProfileConditionType: " + condition.Condition); - } - } - - return false; - } - private static bool IsConditionSatisfied(ProfileCondition condition, double? currentValue) { if (!currentValue.HasValue) diff --git a/MediaBrowser.Model/Dlna/ContainerProfile.cs b/MediaBrowser.Model/Dlna/ContainerProfile.cs index e6691c5139..1d18da6a01 100644 --- a/MediaBrowser.Model/Dlna/ContainerProfile.cs +++ b/MediaBrowser.Model/Dlna/ContainerProfile.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -10,6 +11,7 @@ namespace MediaBrowser.Model.Dlna { [XmlAttribute("type")] public DlnaProfileType Type { get; set; } + public ProfileCondition[] Conditions { get; set; } [XmlAttribute("container")] @@ -45,7 +47,7 @@ namespace MediaBrowser.Model.Dlna public static bool ContainsContainer(string profileContainers, string inputContainer) { var isNegativeList = false; - if (profileContainers != null && profileContainers.StartsWith("-")) + if (profileContainers != null && profileContainers.StartsWith("-", StringComparison.Ordinal)) { isNegativeList = true; profileContainers = profileContainers.Substring(1); diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs index a20f11503c..b055ad41a4 100644 --- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs +++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -32,7 +33,10 @@ namespace MediaBrowser.Model.Dlna DlnaFlags.InteractiveTransferMode | DlnaFlags.DlnaV15; - string dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}", DlnaMaps.FlagsToString(flagValue)); + string dlnaflags = string.Format( + CultureInfo.InvariantCulture, + ";DLNA.ORG_FLAGS={0}", + DlnaMaps.FlagsToString(flagValue)); ResponseProfile mediaProfile = _profile.GetImageMediaProfile(container, width, diff --git a/MediaBrowser.Model/Dlna/DeviceIdentification.cs b/MediaBrowser.Model/Dlna/DeviceIdentification.cs index f1699d930b..85cc9e3c14 100644 --- a/MediaBrowser.Model/Dlna/DeviceIdentification.cs +++ b/MediaBrowser.Model/Dlna/DeviceIdentification.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs index 0cefbbe012..704d4ec375 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfile.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs b/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs index 3475839650..74c32c523e 100644 --- a/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs +++ b/MediaBrowser.Model/Dlna/DeviceProfileInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Dlna diff --git a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs index a5947bbf49..6f4b4ab1bf 100644 --- a/MediaBrowser.Model/Dlna/DirectPlayProfile.cs +++ b/MediaBrowser.Model/Dlna/DirectPlayProfile.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System.Xml.Serialization; diff --git a/MediaBrowser.Model/Dlna/HttpHeaderInfo.cs b/MediaBrowser.Model/Dlna/HttpHeaderInfo.cs index f23a240847..17c4dffcc0 100644 --- a/MediaBrowser.Model/Dlna/HttpHeaderInfo.cs +++ b/MediaBrowser.Model/Dlna/HttpHeaderInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System.Xml.Serialization; diff --git a/MediaBrowser.Model/Dlna/ITranscoderSupport.cs b/MediaBrowser.Model/Dlna/ITranscoderSupport.cs index 7e35cc85ba..d9bd094d9f 100644 --- a/MediaBrowser.Model/Dlna/ITranscoderSupport.cs +++ b/MediaBrowser.Model/Dlna/ITranscoderSupport.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Dlna @@ -5,7 +6,9 @@ namespace MediaBrowser.Model.Dlna public interface ITranscoderSupport { bool CanEncodeToAudioCodec(string codec); + bool CanEncodeToSubtitleCodec(string codec); + bool CanExtractSubtitles(string codec); } @@ -15,10 +18,12 @@ namespace MediaBrowser.Model.Dlna { return true; } + public bool CanEncodeToSubtitleCodec(string codec) { return true; } + public bool CanExtractSubtitles(string codec) { return true; diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs index 4cd318abb3..10e9179c08 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -21,13 +22,13 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(container, "asf", StringComparison.OrdinalIgnoreCase)) { MediaFormatProfile? val = ResolveVideoASFFormat(videoCodec, audioCodec, width, height); - return val.HasValue ? new MediaFormatProfile[] { val.Value } : new MediaFormatProfile[] { }; + return val.HasValue ? new MediaFormatProfile[] { val.Value } : Array.Empty(); } if (string.Equals(container, "mp4", StringComparison.OrdinalIgnoreCase)) { MediaFormatProfile? val = ResolveVideoMP4Format(videoCodec, audioCodec, width, height); - return val.HasValue ? new MediaFormatProfile[] { val.Value } : new MediaFormatProfile[] { }; + return val.HasValue ? new MediaFormatProfile[] { val.Value } : Array.Empty(); } if (string.Equals(container, "avi", StringComparison.OrdinalIgnoreCase)) @@ -61,18 +62,18 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(container, "3gp", StringComparison.OrdinalIgnoreCase)) { MediaFormatProfile? val = ResolveVideo3GPFormat(videoCodec, audioCodec); - return val.HasValue ? new MediaFormatProfile[] { val.Value } : new MediaFormatProfile[] { }; + return val.HasValue ? new MediaFormatProfile[] { val.Value } : Array.Empty(); } if (string.Equals(container, "ogv", StringComparison.OrdinalIgnoreCase) || string.Equals(container, "ogg", StringComparison.OrdinalIgnoreCase)) return new MediaFormatProfile[] { MediaFormatProfile.OGV }; - return new MediaFormatProfile[] { }; + return Array.Empty(); } private MediaFormatProfile[] ResolveVideoMPEG2TSFormat(string videoCodec, string audioCodec, int? width, int? height, TransportStreamTimestamp timestampType) { - string suffix = ""; + string suffix = string.Empty; switch (timestampType) { @@ -92,16 +93,18 @@ namespace MediaBrowser.Model.Dlna if (string.Equals(videoCodec, "mpeg2video", StringComparison.OrdinalIgnoreCase)) { - var list = new List(); - - list.Add(ValueOf("MPEG_TS_SD_NA" + suffix)); - list.Add(ValueOf("MPEG_TS_SD_EU" + suffix)); - list.Add(ValueOf("MPEG_TS_SD_KO" + suffix)); + var list = new List + { + ValueOf("MPEG_TS_SD_NA" + suffix), + ValueOf("MPEG_TS_SD_EU" + suffix), + ValueOf("MPEG_TS_SD_KO" + suffix) + }; if ((timestampType == TransportStreamTimestamp.Valid) && string.Equals(audioCodec, "aac", StringComparison.OrdinalIgnoreCase)) { list.Add(MediaFormatProfile.MPEG_TS_JP_T); } + return list.ToArray(); } if (string.Equals(videoCodec, "h264", StringComparison.OrdinalIgnoreCase)) @@ -115,6 +118,7 @@ namespace MediaBrowser.Model.Dlna { return new MediaFormatProfile[] { MediaFormatProfile.AVC_TS_HD_DTS_ISO }; } + return new MediaFormatProfile[] { MediaFormatProfile.AVC_TS_HD_DTS_T }; } diff --git a/MediaBrowser.Model/Dlna/ProfileCondition.cs b/MediaBrowser.Model/Dlna/ProfileCondition.cs index 2021038d8f..f8b5dee81e 100644 --- a/MediaBrowser.Model/Dlna/ProfileCondition.cs +++ b/MediaBrowser.Model/Dlna/ProfileCondition.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System.Xml.Serialization; @@ -6,18 +7,6 @@ namespace MediaBrowser.Model.Dlna { public class ProfileCondition { - [XmlAttribute("condition")] - public ProfileConditionType Condition { get; set; } - - [XmlAttribute("property")] - public ProfileConditionValue Property { get; set; } - - [XmlAttribute("value")] - public string Value { get; set; } - - [XmlAttribute("isRequired")] - public bool IsRequired { get; set; } - public ProfileCondition() { IsRequired = true; @@ -36,5 +25,17 @@ namespace MediaBrowser.Model.Dlna Value = value; IsRequired = isRequired; } + + [XmlAttribute("condition")] + public ProfileConditionType Condition { get; set; } + + [XmlAttribute("property")] + public ProfileConditionValue Property { get; set; } + + [XmlAttribute("value")] + public string Value { get; set; } + + [XmlAttribute("isRequired")] + public bool IsRequired { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs b/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs index c26eeec77f..30c44fbe0e 100644 --- a/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs +++ b/MediaBrowser.Model/Dlna/ResolutionConfiguration.cs @@ -5,6 +5,7 @@ namespace MediaBrowser.Model.Dlna public class ResolutionConfiguration { public int MaxWidth { get; set; } + public int MaxBitrate { get; set; } public ResolutionConfiguration(int maxWidth, int maxBitrate) diff --git a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs index 8235b72d13..102db3b44e 100644 --- a/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs +++ b/MediaBrowser.Model/Dlna/ResolutionNormalizer.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -17,7 +18,8 @@ namespace MediaBrowser.Model.Dlna new ResolutionConfiguration(3840, 35000000) }; - public static ResolutionOptions Normalize(int? inputBitrate, + public static ResolutionOptions Normalize( + int? inputBitrate, int? unused1, int? unused2, int outputBitrate, @@ -83,6 +85,7 @@ namespace MediaBrowser.Model.Dlna { return .5; } + return 1; } diff --git a/MediaBrowser.Model/Dlna/ResolutionOptions.cs b/MediaBrowser.Model/Dlna/ResolutionOptions.cs index 5ea0252cb1..774592abc7 100644 --- a/MediaBrowser.Model/Dlna/ResolutionOptions.cs +++ b/MediaBrowser.Model/Dlna/ResolutionOptions.cs @@ -5,6 +5,7 @@ namespace MediaBrowser.Model.Dlna public class ResolutionOptions { public int? MaxWidth { get; set; } + public int? MaxHeight { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/ResponseProfile.cs b/MediaBrowser.Model/Dlna/ResponseProfile.cs index c264cb936c..48f53f06c2 100644 --- a/MediaBrowser.Model/Dlna/ResponseProfile.cs +++ b/MediaBrowser.Model/Dlna/ResponseProfile.cs @@ -1,5 +1,7 @@ +#nullable disable #pragma warning disable CS1591 +using System; using System.Xml.Serialization; namespace MediaBrowser.Model.Dlna @@ -28,7 +30,7 @@ namespace MediaBrowser.Model.Dlna public ResponseProfile() { - Conditions = new ProfileCondition[] { }; + Conditions = Array.Empty(); } public string[] GetContainers() diff --git a/MediaBrowser.Model/Dlna/SearchCriteria.cs b/MediaBrowser.Model/Dlna/SearchCriteria.cs index 394fb9af95..94f5bd3dbe 100644 --- a/MediaBrowser.Model/Dlna/SearchCriteria.cs +++ b/MediaBrowser.Model/Dlna/SearchCriteria.cs @@ -34,9 +34,9 @@ namespace MediaBrowser.Model.Dlna public SearchCriteria(string search) { - if (string.IsNullOrEmpty(search)) + if (search.Length == 0) { - throw new ArgumentNullException(nameof(search)); + throw new ArgumentException("String can't be empty.", nameof(search)); } SearchType = SearchType.Unknown; @@ -48,11 +48,10 @@ namespace MediaBrowser.Model.Dlna if (subFactors.Length == 3) { - if (string.Equals("upnp:class", subFactors[0], StringComparison.OrdinalIgnoreCase) && - (string.Equals("=", subFactors[1]) || string.Equals("derivedfrom", subFactors[1], StringComparison.OrdinalIgnoreCase))) + (string.Equals("=", subFactors[1], StringComparison.Ordinal) || string.Equals("derivedfrom", subFactors[1], StringComparison.OrdinalIgnoreCase))) { - if (string.Equals("\"object.item.imageItem\"", subFactors[2]) || string.Equals("\"object.item.imageItem.photo\"", subFactors[2], StringComparison.OrdinalIgnoreCase)) + if (string.Equals("\"object.item.imageItem\"", subFactors[2], StringComparison.Ordinal) || string.Equals("\"object.item.imageItem.photo\"", subFactors[2], StringComparison.OrdinalIgnoreCase)) { SearchType = SearchType.Image; } diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 58755b1719..a18ad36c5a 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -339,6 +340,7 @@ namespace MediaBrowser.Model.Dlna { transcodeReasons.Add(transcodeReason.Value); } + all = false; break; } diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index c9fe679e1f..2444638030 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dlna/SubtitleProfile.cs b/MediaBrowser.Model/Dlna/SubtitleProfile.cs index 6a8f655ac5..f565fb0250 100644 --- a/MediaBrowser.Model/Dlna/SubtitleProfile.cs +++ b/MediaBrowser.Model/Dlna/SubtitleProfile.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System.Xml.Serialization; diff --git a/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs b/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs index 02b3a198c3..2f01836bdf 100644 --- a/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs +++ b/MediaBrowser.Model/Dlna/SubtitleStreamInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Dlna @@ -5,13 +6,21 @@ namespace MediaBrowser.Model.Dlna public class SubtitleStreamInfo { public string Url { get; set; } + public string Language { get; set; } + public string Name { get; set; } + public bool IsForced { get; set; } + public string Format { get; set; } + public string DisplayTitle { get; set; } + public int Index { get; set; } + public SubtitleDeliveryMethod DeliveryMethod { get; set; } + public bool IsExternalUrl { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs index 570ee7baa9..f05e31047c 100644 --- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs +++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System.Xml.Serialization; diff --git a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs index 3dc1fca367..d71013f019 100644 --- a/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs +++ b/MediaBrowser.Model/Dlna/UpnpDeviceInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -9,8 +10,11 @@ namespace MediaBrowser.Model.Dlna public class UpnpDeviceInfo { public Uri Location { get; set; } + public Dictionary Headers { get; set; } + public IPAddress LocalIpAddress { get; set; } + public int LocalPort { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/VideoOptions.cs b/MediaBrowser.Model/Dlna/VideoOptions.cs index 5b12fff1cf..4194f17c6e 100644 --- a/MediaBrowser.Model/Dlna/VideoOptions.cs +++ b/MediaBrowser.Model/Dlna/VideoOptions.cs @@ -8,6 +8,7 @@ namespace MediaBrowser.Model.Dlna public class VideoOptions : AudioOptions { public int? AudioStreamIndex { get; set; } + public int? SubtitleStreamIndex { get; set; } } } diff --git a/MediaBrowser.Model/Dlna/XmlAttribute.cs b/MediaBrowser.Model/Dlna/XmlAttribute.cs index 31603a7542..3a8939a797 100644 --- a/MediaBrowser.Model/Dlna/XmlAttribute.cs +++ b/MediaBrowser.Model/Dlna/XmlAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System.Xml.Serialization; diff --git a/MediaBrowser.Model/Drawing/DrawingUtils.cs b/MediaBrowser.Model/Drawing/DrawingUtils.cs index 0be30b0baf..1512c52337 100644 --- a/MediaBrowser.Model/Drawing/DrawingUtils.cs +++ b/MediaBrowser.Model/Drawing/DrawingUtils.cs @@ -16,7 +16,8 @@ namespace MediaBrowser.Model.Drawing /// A max fixed width, if desired. /// A max fixed height, if desired. /// A new size object. - public static ImageDimensions Resize(ImageDimensions size, + public static ImageDimensions Resize( + ImageDimensions size, int width, int height, int maxWidth, @@ -62,7 +63,7 @@ namespace MediaBrowser.Model.Drawing /// Height of the current. /// Width of the current. /// The new height. - /// the new width + /// The new width. private static int GetNewWidth(int currentHeight, int currentWidth, int newHeight) => Convert.ToInt32((double)newHeight / currentHeight * currentWidth); diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 607355d8d3..55393d32c6 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dto/BaseItemPerson.cs b/MediaBrowser.Model/Dto/BaseItemPerson.cs index 5b7eefd70b..b080f3e4ac 100644 --- a/MediaBrowser.Model/Dto/BaseItemPerson.cs +++ b/MediaBrowser.Model/Dto/BaseItemPerson.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Text.Json.Serialization; namespace MediaBrowser.Model.Dto diff --git a/MediaBrowser.Model/Dto/IHasServerId.cs b/MediaBrowser.Model/Dto/IHasServerId.cs index 8c9798c5cb..c754d276c5 100644 --- a/MediaBrowser.Model/Dto/IHasServerId.cs +++ b/MediaBrowser.Model/Dto/IHasServerId.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Dto diff --git a/MediaBrowser.Model/Dto/ImageByNameInfo.cs b/MediaBrowser.Model/Dto/ImageByNameInfo.cs index d2e43634d2..06cc3e73cf 100644 --- a/MediaBrowser.Model/Dto/ImageByNameInfo.cs +++ b/MediaBrowser.Model/Dto/ImageByNameInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Dto diff --git a/MediaBrowser.Model/Dto/ImageInfo.cs b/MediaBrowser.Model/Dto/ImageInfo.cs index 57942ac23b..1e9b47267c 100644 --- a/MediaBrowser.Model/Dto/ImageInfo.cs +++ b/MediaBrowser.Model/Dto/ImageInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using MediaBrowser.Model.Entities; namespace MediaBrowser.Model.Dto @@ -20,9 +21,9 @@ namespace MediaBrowser.Model.Dto public int? ImageIndex { get; set; } /// - /// The image tag + /// Gets or sets the image tag. /// - public string ImageTag; + public string ImageTag { get; set; } /// /// Gets or sets the path. diff --git a/MediaBrowser.Model/Dto/ImageOptions.cs b/MediaBrowser.Model/Dto/ImageOptions.cs index 4e672a007e..158e622a85 100644 --- a/MediaBrowser.Model/Dto/ImageOptions.cs +++ b/MediaBrowser.Model/Dto/ImageOptions.cs @@ -1,3 +1,4 @@ +#nullable disable using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; @@ -8,6 +9,14 @@ namespace MediaBrowser.Model.Dto /// public class ImageOptions { + /// + /// Initializes a new instance of the class. + /// + public ImageOptions() + { + EnableImageEnhancers = true; + } + /// /// Gets or sets the type of the image. /// @@ -98,13 +107,5 @@ namespace MediaBrowser.Model.Dto /// /// The color of the background. public string BackgroundColor { get; set; } - - /// - /// Initializes a new instance of the class. - /// - public ImageOptions() - { - EnableImageEnhancers = true; - } } } diff --git a/MediaBrowser.Model/Dto/ItemIndex.cs b/MediaBrowser.Model/Dto/ItemIndex.cs deleted file mode 100644 index 525576d614..0000000000 --- a/MediaBrowser.Model/Dto/ItemIndex.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace MediaBrowser.Model.Dto -{ - /// - /// Class ItemIndex. - /// - public class ItemIndex - { - /// - /// Gets or sets the name. - /// - /// The name. - public string Name { get; set; } - - /// - /// Gets or sets the item count. - /// - /// The item count. - public int ItemCount { get; set; } - } -} diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs index 29613adbf4..74c2cb4f41 100644 --- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs +++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs index 21d8a31f23..1d840a3000 100644 --- a/MediaBrowser.Model/Dto/MetadataEditorInfo.cs +++ b/MediaBrowser.Model/Dto/MetadataEditorInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dto/NameIdPair.cs b/MediaBrowser.Model/Dto/NameIdPair.cs index 1b4800863c..efb2c157c2 100644 --- a/MediaBrowser.Model/Dto/NameIdPair.cs +++ b/MediaBrowser.Model/Dto/NameIdPair.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dto/NameValuePair.cs b/MediaBrowser.Model/Dto/NameValuePair.cs index 74040c2cb4..e71ff3c21b 100644 --- a/MediaBrowser.Model/Dto/NameValuePair.cs +++ b/MediaBrowser.Model/Dto/NameValuePair.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Dto @@ -6,7 +7,6 @@ namespace MediaBrowser.Model.Dto { public NameValuePair() { - } public NameValuePair(string name, string value) diff --git a/MediaBrowser.Model/Dto/RecommendationDto.cs b/MediaBrowser.Model/Dto/RecommendationDto.cs index bc97dd6f1d..107f415406 100644 --- a/MediaBrowser.Model/Dto/RecommendationDto.cs +++ b/MediaBrowser.Model/Dto/RecommendationDto.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Dto/UserDto.cs b/MediaBrowser.Model/Dto/UserDto.cs index d36706c387..40222c9dca 100644 --- a/MediaBrowser.Model/Dto/UserDto.cs +++ b/MediaBrowser.Model/Dto/UserDto.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Users; diff --git a/MediaBrowser.Model/Dto/UserItemDataDto.cs b/MediaBrowser.Model/Dto/UserItemDataDto.cs index 92f06c9733..adb2cd2ab3 100644 --- a/MediaBrowser.Model/Dto/UserItemDataDto.cs +++ b/MediaBrowser.Model/Dto/UserItemDataDto.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace MediaBrowser.Model.Dto diff --git a/MediaBrowser.Model/Entities/ChapterInfo.cs b/MediaBrowser.Model/Entities/ChapterInfo.cs index bea7ec1dba..45554c3dc0 100644 --- a/MediaBrowser.Model/Entities/ChapterInfo.cs +++ b/MediaBrowser.Model/Entities/ChapterInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Entities/DisplayPreferences.cs b/MediaBrowser.Model/Entities/DisplayPreferences.cs index 2cd8bd3065..0e5db01dd5 100644 --- a/MediaBrowser.Model/Entities/DisplayPreferences.cs +++ b/MediaBrowser.Model/Entities/DisplayPreferences.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; namespace MediaBrowser.Model.Entities diff --git a/MediaBrowser.Model/Entities/IHasProviderIds.cs b/MediaBrowser.Model/Entities/IHasProviderIds.cs index c117efde94..1310f68ae5 100644 --- a/MediaBrowser.Model/Entities/IHasProviderIds.cs +++ b/MediaBrowser.Model/Entities/IHasProviderIds.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace MediaBrowser.Model.Entities { /// - /// Since BaseItem and DTOBaseItem both have ProviderIds, this interface helps avoid code repition by using extension methods. + /// Since BaseItem and DTOBaseItem both have ProviderIds, this interface helps avoid code repetition by using extension methods. /// public interface IHasProviderIds { diff --git a/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs b/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs index b98c002405..6dd6653dc7 100644 --- a/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs +++ b/MediaBrowser.Model/Entities/LibraryUpdateInfo.cs @@ -5,15 +5,29 @@ using System; namespace MediaBrowser.Model.Entities { /// - /// Class LibraryUpdateInfo + /// Class LibraryUpdateInfo. /// public class LibraryUpdateInfo { + /// + /// Initializes a new instance of the class. + /// + public LibraryUpdateInfo() + { + FoldersAddedTo = Array.Empty(); + FoldersRemovedFrom = Array.Empty(); + ItemsAdded = Array.Empty(); + ItemsRemoved = Array.Empty(); + ItemsUpdated = Array.Empty(); + CollectionFolders = Array.Empty(); + } + /// /// Gets or sets the folders added to. /// /// The folders added to. public string[] FoldersAddedTo { get; set; } + /// /// Gets or sets the folders removed from. /// @@ -41,18 +55,5 @@ namespace MediaBrowser.Model.Entities public string[] CollectionFolders { get; set; } public bool IsEmpty => FoldersAddedTo.Length == 0 && FoldersRemovedFrom.Length == 0 && ItemsAdded.Length == 0 && ItemsRemoved.Length == 0 && ItemsUpdated.Length == 0 && CollectionFolders.Length == 0; - - /// - /// Initializes a new instance of the class. - /// - public LibraryUpdateInfo() - { - FoldersAddedTo = Array.Empty(); - FoldersRemovedFrom = Array.Empty(); - ItemsAdded = Array.Empty(); - ItemsRemoved = Array.Empty(); - ItemsUpdated = Array.Empty(); - CollectionFolders = Array.Empty(); - } } } diff --git a/MediaBrowser.Model/Entities/MediaAttachment.cs b/MediaBrowser.Model/Entities/MediaAttachment.cs index 167be18c95..34e3eabc97 100644 --- a/MediaBrowser.Model/Entities/MediaAttachment.cs +++ b/MediaBrowser.Model/Entities/MediaAttachment.cs @@ -1,3 +1,4 @@ +#nullable disable namespace MediaBrowser.Model.Entities { /// diff --git a/MediaBrowser.Model/Entities/MediaStream.cs b/MediaBrowser.Model/Entities/MediaStream.cs index e7e8d7cecd..d68f37c9c6 100644 --- a/MediaBrowser.Model/Entities/MediaStream.cs +++ b/MediaBrowser.Model/Entities/MediaStream.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Entities/MediaUrl.cs b/MediaBrowser.Model/Entities/MediaUrl.cs index e441437553..74f982437f 100644 --- a/MediaBrowser.Model/Entities/MediaUrl.cs +++ b/MediaBrowser.Model/Entities/MediaUrl.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Entities diff --git a/MediaBrowser.Model/Entities/PackageReviewInfo.cs b/MediaBrowser.Model/Entities/PackageReviewInfo.cs index a034de8ba8..1ebbc33231 100644 --- a/MediaBrowser.Model/Entities/PackageReviewInfo.cs +++ b/MediaBrowser.Model/Entities/PackageReviewInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -7,32 +8,32 @@ namespace MediaBrowser.Model.Entities public class PackageReviewInfo { /// - /// The package id (database key) for this review + /// Gets or sets the package id (database key) for this review. /// public int id { get; set; } /// - /// The rating value + /// Gets or sets the rating value. /// public int rating { get; set; } /// - /// Whether or not this review recommends this item + /// Gets or sets whether or not this review recommends this item. /// public bool recommend { get; set; } /// - /// A short description of the review + /// Gets or sets a short description of the review. /// public string title { get; set; } /// - /// A full review + /// Gets or sets the full review. /// public string review { get; set; } /// - /// Time of review + /// Gets or sets the time of review. /// public DateTime timestamp { get; set; } diff --git a/MediaBrowser.Model/Entities/ParentalRating.cs b/MediaBrowser.Model/Entities/ParentalRating.cs index 4b37bd64af..17b2868a31 100644 --- a/MediaBrowser.Model/Entities/ParentalRating.cs +++ b/MediaBrowser.Model/Entities/ParentalRating.cs @@ -1,12 +1,23 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Entities { /// - /// Class ParentalRating + /// Class ParentalRating. /// public class ParentalRating { + public ParentalRating() + { + } + + public ParentalRating(string name, int value) + { + Name = name; + Value = value; + } + /// /// Gets or sets the name. /// @@ -18,16 +29,5 @@ namespace MediaBrowser.Model.Entities /// /// The value. public int Value { get; set; } - - public ParentalRating() - { - - } - - public ParentalRating(string name, int value) - { - Name = name; - Value = value; - } } } diff --git a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs index cd387bd546..e089dd1e54 100644 --- a/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs +++ b/MediaBrowser.Model/Entities/ProviderIdsExtensions.cs @@ -20,23 +20,23 @@ namespace MediaBrowser.Model.Entities } /// - /// Gets a provider id + /// Gets a provider id. /// /// The instance. /// The provider. /// System.String. - public static string GetProviderId(this IHasProviderIds instance, MetadataProviders provider) + public static string? GetProviderId(this IHasProviderIds instance, MetadataProviders provider) { return instance.GetProviderId(provider.ToString()); } /// - /// Gets a provider id + /// Gets a provider id. /// /// The instance. /// The name. /// System.String. - public static string GetProviderId(this IHasProviderIds instance, string name) + public static string? GetProviderId(this IHasProviderIds instance, string name) { if (instance == null) { @@ -53,7 +53,7 @@ namespace MediaBrowser.Model.Entities } /// - /// Sets a provider id + /// Sets a provider id. /// /// The instance. /// The name. @@ -89,7 +89,7 @@ namespace MediaBrowser.Model.Entities } /// - /// Sets a provider id + /// Sets a provider id. /// /// The instance. /// The provider. diff --git a/MediaBrowser.Model/Entities/VirtualFolderInfo.cs b/MediaBrowser.Model/Entities/VirtualFolderInfo.cs index dd30c9c842..2de02e403c 100644 --- a/MediaBrowser.Model/Entities/VirtualFolderInfo.cs +++ b/MediaBrowser.Model/Entities/VirtualFolderInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Events/GenericEventArgs.cs b/MediaBrowser.Model/Events/GenericEventArgs.cs index 1ef0b25c98..44f60f8115 100644 --- a/MediaBrowser.Model/Events/GenericEventArgs.cs +++ b/MediaBrowser.Model/Events/GenericEventArgs.cs @@ -22,12 +22,5 @@ namespace MediaBrowser.Model.Events { Argument = arg; } - - /// - /// Initializes a new instance of the class. - /// - public GenericEventArgs() - { - } } } diff --git a/MediaBrowser.Model/Extensions/ListHelper.cs b/MediaBrowser.Model/Extensions/ListHelper.cs index 90ce6f2e5e..b893a3509a 100644 --- a/MediaBrowser.Model/Extensions/ListHelper.cs +++ b/MediaBrowser.Model/Extensions/ListHelper.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -21,6 +22,7 @@ namespace MediaBrowser.Model.Extensions return true; } } + return false; } } diff --git a/MediaBrowser.Model/Extensions/StringHelper.cs b/MediaBrowser.Model/Extensions/StringHelper.cs index f819a295c6..8ffa3c4ba6 100644 --- a/MediaBrowser.Model/Extensions/StringHelper.cs +++ b/MediaBrowser.Model/Extensions/StringHelper.cs @@ -12,9 +12,9 @@ namespace MediaBrowser.Model.Extensions /// The string with the first character as uppercase. public static string FirstToUpper(string str) { - if (string.IsNullOrEmpty(str)) + if (str.Length == 0) { - return string.Empty; + return str; } if (char.IsUpper(str[0])) diff --git a/MediaBrowser.Model/Globalization/CountryInfo.cs b/MediaBrowser.Model/Globalization/CountryInfo.cs index 72362f4f31..6f6979316b 100644 --- a/MediaBrowser.Model/Globalization/CountryInfo.cs +++ b/MediaBrowser.Model/Globalization/CountryInfo.cs @@ -1,3 +1,4 @@ +#nullable disable namespace MediaBrowser.Model.Globalization { /// diff --git a/MediaBrowser.Model/Globalization/CultureDto.cs b/MediaBrowser.Model/Globalization/CultureDto.cs index f415840b0f..6af4a872ce 100644 --- a/MediaBrowser.Model/Globalization/CultureDto.cs +++ b/MediaBrowser.Model/Globalization/CultureDto.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Globalization/ILocalizationManager.cs b/MediaBrowser.Model/Globalization/ILocalizationManager.cs index 613bfca695..baefeb39cf 100644 --- a/MediaBrowser.Model/Globalization/ILocalizationManager.cs +++ b/MediaBrowser.Model/Globalization/ILocalizationManager.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; using System.Globalization; using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Model/Globalization/LocalizationOption.cs b/MediaBrowser.Model/Globalization/LocalizationOption.cs index 00caf5e118..81f47d9783 100644 --- a/MediaBrowser.Model/Globalization/LocalizationOption.cs +++ b/MediaBrowser.Model/Globalization/LocalizationOption.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Globalization @@ -11,6 +12,7 @@ namespace MediaBrowser.Model.Globalization } public string Name { get; set; } + public string Value { get; set; } } } diff --git a/MediaBrowser.Model/IO/FileSystemEntryInfo.cs b/MediaBrowser.Model/IO/FileSystemEntryInfo.cs index a197f0fbe0..36ff5d041f 100644 --- a/MediaBrowser.Model/IO/FileSystemEntryInfo.cs +++ b/MediaBrowser.Model/IO/FileSystemEntryInfo.cs @@ -1,26 +1,39 @@ namespace MediaBrowser.Model.IO { /// - /// Class FileSystemEntryInfo + /// Class FileSystemEntryInfo. /// public class FileSystemEntryInfo { /// - /// Gets or sets the name. + /// Initializes a new instance of the class. + /// + /// The filename. + /// The file path. + /// The file type. + public FileSystemEntryInfo(string name, string path, FileSystemEntryType type) + { + Name = name; + Path = path; + Type = type; + } + + /// + /// Gets the name. /// /// The name. - public string Name { get; set; } + public string Name { get; } /// - /// Gets or sets the path. + /// Gets the path. /// /// The path. - public string Path { get; set; } + public string Path { get; } /// - /// Gets or sets the type. + /// Gets the type. /// /// The type. - public FileSystemEntryType Type { get; set; } + public FileSystemEntryType Type { get; } } } diff --git a/MediaBrowser.Model/IO/FileSystemMetadata.cs b/MediaBrowser.Model/IO/FileSystemMetadata.cs index 4b9102392c..b23119d08f 100644 --- a/MediaBrowser.Model/IO/FileSystemMetadata.cs +++ b/MediaBrowser.Model/IO/FileSystemMetadata.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/IO/IFileSystem.cs b/MediaBrowser.Model/IO/IFileSystem.cs index 53f23a8e0a..bba69d4b46 100644 --- a/MediaBrowser.Model/IO/IFileSystem.cs +++ b/MediaBrowser.Model/IO/IFileSystem.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/IO/IIsoManager.cs b/MediaBrowser.Model/IO/IIsoManager.cs index 8b6af019d6..299bb0a213 100644 --- a/MediaBrowser.Model/IO/IIsoManager.cs +++ b/MediaBrowser.Model/IO/IIsoManager.cs @@ -16,7 +16,6 @@ namespace MediaBrowser.Model.IO /// The iso path. /// The cancellation token. /// IsoMount. - /// isoPath /// Unable to create mount. Task Mount(string isoPath, CancellationToken cancellationToken); diff --git a/MediaBrowser.Model/IO/IIsoMount.cs b/MediaBrowser.Model/IO/IIsoMount.cs index 72ec673ee1..ea65d976a0 100644 --- a/MediaBrowser.Model/IO/IIsoMount.cs +++ b/MediaBrowser.Model/IO/IIsoMount.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Model.IO public interface IIsoMount : IDisposable { /// - /// Gets or sets the iso path. + /// Gets the iso path. /// /// The iso path. string IsoPath { get; } diff --git a/MediaBrowser.Model/IO/IIsoMounter.cs b/MediaBrowser.Model/IO/IIsoMounter.cs index 83fdb5fd6b..0d257395a9 100644 --- a/MediaBrowser.Model/IO/IIsoMounter.cs +++ b/MediaBrowser.Model/IO/IIsoMounter.cs @@ -9,6 +9,12 @@ namespace MediaBrowser.Model.IO { public interface IIsoMounter { + /// + /// Gets the name. + /// + /// The name. + string Name { get; } + /// /// Mounts the specified iso path. /// @@ -25,11 +31,5 @@ namespace MediaBrowser.Model.IO /// The path. /// true if this instance can mount the specified path; otherwise, false. bool CanMount(string path); - - /// - /// Gets the name. - /// - /// The name. - string Name { get; } } } diff --git a/MediaBrowser.Model/IO/IStreamHelper.cs b/MediaBrowser.Model/IO/IStreamHelper.cs index e348cd7259..af5ba5b17f 100644 --- a/MediaBrowser.Model/IO/IStreamHelper.cs +++ b/MediaBrowser.Model/IO/IStreamHelper.cs @@ -14,6 +14,7 @@ namespace MediaBrowser.Model.IO Task CopyToAsync(Stream source, Stream destination, int bufferSize, int emptyReadLimit, CancellationToken cancellationToken); Task CopyToAsync(Stream source, Stream destination, CancellationToken cancellationToken); + Task CopyToAsync(Stream source, Stream destination, long copyLength, CancellationToken cancellationToken); Task CopyUntilCancelled(Stream source, Stream target, int bufferSize, CancellationToken cancellationToken); diff --git a/MediaBrowser.Model/Library/UserViewQuery.cs b/MediaBrowser.Model/Library/UserViewQuery.cs index a538efd257..8a49b68637 100644 --- a/MediaBrowser.Model/Library/UserViewQuery.cs +++ b/MediaBrowser.Model/Library/UserViewQuery.cs @@ -6,6 +6,12 @@ namespace MediaBrowser.Model.Library { public class UserViewQuery { + public UserViewQuery() + { + IncludeExternalContent = true; + PresetViews = Array.Empty(); + } + /// /// Gets or sets the user identifier. /// @@ -25,11 +31,5 @@ namespace MediaBrowser.Model.Library public bool IncludeHidden { get; set; } public string[] PresetViews { get; set; } - - public UserViewQuery() - { - IncludeExternalContent = true; - PresetViews = Array.Empty(); - } } } diff --git a/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs index 064ce65202..45970cf6b1 100644 --- a/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/BaseTimerInfoDto.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/LiveTv/GuideInfo.cs b/MediaBrowser.Model/LiveTv/GuideInfo.cs index a224d73b7e..b1cc8cfdf8 100644 --- a/MediaBrowser.Model/LiveTv/GuideInfo.cs +++ b/MediaBrowser.Model/LiveTv/GuideInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs index 8154fbd0ef..d1a94d8b30 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvChannelQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/LiveTv/LiveTvInfo.cs b/MediaBrowser.Model/LiveTv/LiveTvInfo.cs index 85b77af245..9767509d09 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvInfo.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvInfo.cs @@ -6,6 +6,12 @@ namespace MediaBrowser.Model.LiveTv { public class LiveTvInfo { + public LiveTvInfo() + { + Services = Array.Empty(); + EnabledUsers = Array.Empty(); + } + /// /// Gets or sets the services. /// @@ -23,11 +29,5 @@ namespace MediaBrowser.Model.LiveTv /// /// The enabled users. public string[] EnabledUsers { get; set; } - - public LiveTvInfo() - { - Services = Array.Empty(); - EnabledUsers = Array.Empty(); - } } } diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs index dc8e0f91bf..69c43efd47 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs b/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs index 09e900643a..856f638c5c 100644 --- a/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs +++ b/MediaBrowser.Model/LiveTv/LiveTvServiceInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/LiveTv/RecordingQuery.cs b/MediaBrowser.Model/LiveTv/RecordingQuery.cs index c75092b79c..2649829300 100644 --- a/MediaBrowser.Model/LiveTv/RecordingQuery.cs +++ b/MediaBrowser.Model/LiveTv/RecordingQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs index e30dd84dcd..90422d19c3 100644 --- a/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/SeriesTimerInfoDto.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -14,7 +15,7 @@ namespace MediaBrowser.Model.LiveTv public SeriesTimerInfoDto() { ImageTags = new Dictionary(); - Days = new DayOfWeek[] { }; + Days = Array.Empty(); Type = "SeriesTimer"; } diff --git a/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs b/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs index bb553a5766..bda46dd2bc 100644 --- a/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs +++ b/MediaBrowser.Model/LiveTv/SeriesTimerQuery.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Model.LiveTv /// Gets or sets the sort by - SortName, Priority /// /// The sort by. - public string SortBy { get; set; } + public string? SortBy { get; set; } /// /// Gets or sets the sort order. diff --git a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs index a1fbc51776..19039d4488 100644 --- a/MediaBrowser.Model/LiveTv/TimerInfoDto.cs +++ b/MediaBrowser.Model/LiveTv/TimerInfoDto.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using MediaBrowser.Model.Dto; diff --git a/MediaBrowser.Model/LiveTv/TimerQuery.cs b/MediaBrowser.Model/LiveTv/TimerQuery.cs index 1ef6dd67e2..367c45b9df 100644 --- a/MediaBrowser.Model/LiveTv/TimerQuery.cs +++ b/MediaBrowser.Model/LiveTv/TimerQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.LiveTv diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 0fdfe57619..b24409fcc2 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -12,6 +12,8 @@ false true true + enable + latest diff --git a/MediaBrowser.Model/MediaInfo/AudioCodec.cs b/MediaBrowser.Model/MediaInfo/AudioCodec.cs index dcb6fa270d..8b17757b89 100644 --- a/MediaBrowser.Model/MediaInfo/AudioCodec.cs +++ b/MediaBrowser.Model/MediaInfo/AudioCodec.cs @@ -10,9 +10,9 @@ namespace MediaBrowser.Model.MediaInfo public static string GetFriendlyName(string codec) { - if (string.IsNullOrEmpty(codec)) + if (codec.Length == 0) { - return string.Empty; + return codec; } switch (codec.ToLowerInvariant()) diff --git a/MediaBrowser.Model/MediaInfo/BlurayDiscInfo.cs b/MediaBrowser.Model/MediaInfo/BlurayDiscInfo.cs index 29ba10dbbf..83f982a5c8 100644 --- a/MediaBrowser.Model/MediaInfo/BlurayDiscInfo.cs +++ b/MediaBrowser.Model/MediaInfo/BlurayDiscInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index 52348f8026..ea5d4e7d77 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -7,6 +8,13 @@ namespace MediaBrowser.Model.MediaInfo { public class LiveStreamRequest { + public LiveStreamRequest() + { + EnableDirectPlay = true; + EnableDirectStream = true; + DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http }; + } + public string OpenToken { get; set; } public Guid UserId { get; set; } public string PlaySessionId { get; set; } @@ -22,12 +30,7 @@ namespace MediaBrowser.Model.MediaInfo public bool EnableDirectStream { get; set; } public MediaProtocol[] DirectPlayProtocols { get; set; } - public LiveStreamRequest() - { - EnableDirectPlay = true; - EnableDirectStream = true; - DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http }; - } + public LiveStreamRequest(AudioOptions options) { @@ -38,8 +41,7 @@ namespace MediaBrowser.Model.MediaInfo DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http }; - var videoOptions = options as VideoOptions; - if (videoOptions != null) + if (options is VideoOptions videoOptions) { AudioStreamIndex = videoOptions.AudioStreamIndex; SubtitleStreamIndex = videoOptions.SubtitleStreamIndex; diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs b/MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs index 45b8fcce99..f017c1a117 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamResponse.cs @@ -6,6 +6,11 @@ namespace MediaBrowser.Model.MediaInfo { public class LiveStreamResponse { - public MediaSourceInfo MediaSource { get; set; } + public LiveStreamResponse(MediaSourceInfo mediaSource) + { + MediaSource = mediaSource; + } + + public MediaSourceInfo MediaSource { get; } } } diff --git a/MediaBrowser.Model/MediaInfo/MediaInfo.cs b/MediaBrowser.Model/MediaInfo/MediaInfo.cs index ad174f15d9..97b9799357 100644 --- a/MediaBrowser.Model/MediaInfo/MediaInfo.cs +++ b/MediaBrowser.Model/MediaInfo/MediaInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs index a2f1634222..82e13e0ebe 100644 --- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs +++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs index 440818c3ef..2733501822 100644 --- a/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs +++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs @@ -20,7 +20,7 @@ namespace MediaBrowser.Model.MediaInfo /// Gets or sets the play session identifier. /// /// The play session identifier. - public string PlaySessionId { get; set; } + public string? PlaySessionId { get; set; } /// /// Gets or sets the error code. diff --git a/MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs b/MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs index 5b0ccb28a4..72bb3d9c63 100644 --- a/MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs +++ b/MediaBrowser.Model/MediaInfo/SubtitleTrackEvent.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.MediaInfo @@ -5,8 +6,11 @@ namespace MediaBrowser.Model.MediaInfo public class SubtitleTrackEvent { public string Id { get; set; } + public string Text { get; set; } + public long StartPositionTicks { get; set; } + public long EndPositionTicks { get; set; } } } diff --git a/MediaBrowser.Model/Net/EndPointInfo.cs b/MediaBrowser.Model/Net/EndPointInfo.cs index f5ac3d1698..034734a9e1 100644 --- a/MediaBrowser.Model/Net/EndPointInfo.cs +++ b/MediaBrowser.Model/Net/EndPointInfo.cs @@ -5,6 +5,7 @@ namespace MediaBrowser.Model.Net public class EndPointInfo { public bool IsLocal { get; set; } + public bool IsInNetwork { get; set; } } } diff --git a/MediaBrowser.Model/Net/ISocket.cs b/MediaBrowser.Model/Net/ISocket.cs index 2bfbfcb20c..5b6ed92df1 100644 --- a/MediaBrowser.Model/Net/ISocket.cs +++ b/MediaBrowser.Model/Net/ISocket.cs @@ -17,6 +17,7 @@ namespace MediaBrowser.Model.Net Task ReceiveAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken); IAsyncResult BeginReceive(byte[] buffer, int offset, int count, AsyncCallback callback); + SocketReceiveResult EndReceive(IAsyncResult result); /// diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs index 68bcc590c4..cfac4d1e2d 100644 --- a/MediaBrowser.Model/Net/MimeTypes.cs +++ b/MediaBrowser.Model/Net/MimeTypes.cs @@ -8,12 +8,12 @@ using System.Linq; namespace MediaBrowser.Model.Net { /// - /// Class MimeTypes + /// Class MimeTypes. /// public static class MimeTypes { /// - /// Any extension in this list is considered a video file + /// Any extension in this list is considered a video file. /// private static readonly HashSet _videoFileExtensions = new HashSet(StringComparer.OrdinalIgnoreCase) { @@ -141,16 +141,16 @@ namespace MediaBrowser.Model.Net return dict; } - public static string GetMimeType(string path) => GetMimeType(path, true); + public static string? GetMimeType(string path) => GetMimeType(path, true); /// /// Gets the type of the MIME. /// - public static string GetMimeType(string path, bool enableStreamDefault) + public static string? GetMimeType(string path, bool enableStreamDefault) { - if (string.IsNullOrEmpty(path)) + if (path.Length == 0) { - throw new ArgumentNullException(nameof(path)); + throw new ArgumentException("String can't be empty.", nameof(path)); } var ext = Path.GetExtension(path); @@ -188,11 +188,11 @@ namespace MediaBrowser.Model.Net return enableStreamDefault ? "application/octet-stream" : null; } - public static string ToExtension(string mimeType) + public static string? ToExtension(string mimeType) { - if (string.IsNullOrEmpty(mimeType)) + if (mimeType.Length == 0) { - throw new ArgumentNullException(nameof(mimeType)); + throw new ArgumentException("String can't be empty.", nameof(mimeType)); } // handle text/html; charset=UTF-8 diff --git a/MediaBrowser.Model/Net/NetworkShare.cs b/MediaBrowser.Model/Net/NetworkShare.cs index 744c6ec14e..a40cf73e49 100644 --- a/MediaBrowser.Model/Net/NetworkShare.cs +++ b/MediaBrowser.Model/Net/NetworkShare.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Net diff --git a/MediaBrowser.Model/Net/SocketReceiveResult.cs b/MediaBrowser.Model/Net/SocketReceiveResult.cs index 141ae16089..54139fe9c5 100644 --- a/MediaBrowser.Model/Net/SocketReceiveResult.cs +++ b/MediaBrowser.Model/Net/SocketReceiveResult.cs @@ -1,4 +1,4 @@ -#pragma warning disable CS1591 +#nullable disable using System.Net; @@ -10,12 +10,12 @@ namespace MediaBrowser.Model.Net public sealed class SocketReceiveResult { /// - /// The buffer to place received data into. + /// Gets or sets the buffer to place received data into. /// public byte[] Buffer { get; set; } /// - /// The number of bytes received. + /// Gets or sets the number of bytes received. /// public int ReceivedBytes { get; set; } @@ -23,6 +23,10 @@ namespace MediaBrowser.Model.Net /// The the data was received from. /// public IPEndPoint RemoteEndPoint { get; set; } + + /// + /// The local . + /// public IPAddress LocalIPAddress { get; set; } } } diff --git a/MediaBrowser.Model/Net/WebSocketMessage.cs b/MediaBrowser.Model/Net/WebSocketMessage.cs index 7575224d4e..962b81b959 100644 --- a/MediaBrowser.Model/Net/WebSocketMessage.cs +++ b/MediaBrowser.Model/Net/WebSocketMessage.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Net diff --git a/MediaBrowser.Model/Notifications/NotificationOption.cs b/MediaBrowser.Model/Notifications/NotificationOption.cs index 4fb724515c..144949a3b7 100644 --- a/MediaBrowser.Model/Notifications/NotificationOption.cs +++ b/MediaBrowser.Model/Notifications/NotificationOption.cs @@ -6,6 +6,15 @@ namespace MediaBrowser.Model.Notifications { public class NotificationOption { + public NotificationOption(string type) + { + Type = type; + + DisabledServices = Array.Empty(); + DisabledMonitorUsers = Array.Empty(); + SendToUsers = Array.Empty(); + } + public string Type { get; set; } /// @@ -35,12 +44,5 @@ namespace MediaBrowser.Model.Notifications /// /// The send to user mode. public SendToUserType SendToUserMode { get; set; } - - public NotificationOption() - { - DisabledServices = Array.Empty(); - DisabledMonitorUsers = Array.Empty(); - SendToUsers = Array.Empty(); - } } } diff --git a/MediaBrowser.Model/Notifications/NotificationOptions.cs b/MediaBrowser.Model/Notifications/NotificationOptions.cs index 79a128e9be..7b299b1aaa 100644 --- a/MediaBrowser.Model/Notifications/NotificationOptions.cs +++ b/MediaBrowser.Model/Notifications/NotificationOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -14,63 +15,53 @@ namespace MediaBrowser.Model.Notifications { Options = new[] { - new NotificationOption + new NotificationOption(NotificationType.TaskFailed.ToString()) { - Type = NotificationType.TaskFailed.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.ServerRestartRequired.ToString()) { - Type = NotificationType.ServerRestartRequired.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.ApplicationUpdateAvailable.ToString()) { - Type = NotificationType.ApplicationUpdateAvailable.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.ApplicationUpdateInstalled.ToString()) { - Type = NotificationType.ApplicationUpdateInstalled.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.PluginUpdateInstalled.ToString()) { - Type = NotificationType.PluginUpdateInstalled.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.PluginUninstalled.ToString()) { - Type = NotificationType.PluginUninstalled.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.InstallationFailed.ToString()) { - Type = NotificationType.InstallationFailed.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.PluginInstalled.ToString()) { - Type = NotificationType.PluginInstalled.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.PluginError.ToString()) { - Type = NotificationType.PluginError.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins }, - new NotificationOption + new NotificationOption(NotificationType.UserLockedOut.ToString()) { - Type = NotificationType.UserLockedOut.ToString(), Enabled = true, SendToUserMode = SendToUserType.Admins } @@ -81,8 +72,12 @@ namespace MediaBrowser.Model.Notifications { foreach (NotificationOption i in Options) { - if (string.Equals(type, i.Type, StringComparison.OrdinalIgnoreCase)) return i; + if (string.Equals(type, i.Type, StringComparison.OrdinalIgnoreCase)) + { + return i; + } } + return null; } diff --git a/MediaBrowser.Model/Notifications/NotificationRequest.cs b/MediaBrowser.Model/Notifications/NotificationRequest.cs index ffcfab24ff..febc2bc099 100644 --- a/MediaBrowser.Model/Notifications/NotificationRequest.cs +++ b/MediaBrowser.Model/Notifications/NotificationRequest.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Notifications/NotificationTypeInfo.cs b/MediaBrowser.Model/Notifications/NotificationTypeInfo.cs index bfa163b402..402fbe81a0 100644 --- a/MediaBrowser.Model/Notifications/NotificationTypeInfo.cs +++ b/MediaBrowser.Model/Notifications/NotificationTypeInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Notifications diff --git a/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs b/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs index b7003c4c8a..ef435b21ec 100644 --- a/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs +++ b/MediaBrowser.Model/Playlists/PlaylistCreationRequest.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Playlists/PlaylistCreationResult.cs b/MediaBrowser.Model/Playlists/PlaylistCreationResult.cs index 4f2067b98a..f3a1518ed1 100644 --- a/MediaBrowser.Model/Playlists/PlaylistCreationResult.cs +++ b/MediaBrowser.Model/Playlists/PlaylistCreationResult.cs @@ -4,6 +4,11 @@ namespace MediaBrowser.Model.Playlists { public class PlaylistCreationResult { - public string Id { get; set; } + public PlaylistCreationResult(string id) + { + Id = id; + } + + public string Id { get; } } } diff --git a/MediaBrowser.Model/Playlists/PlaylistItemQuery.cs b/MediaBrowser.Model/Playlists/PlaylistItemQuery.cs deleted file mode 100644 index 324a38e700..0000000000 --- a/MediaBrowser.Model/Playlists/PlaylistItemQuery.cs +++ /dev/null @@ -1,39 +0,0 @@ -#pragma warning disable CS1591 - -using MediaBrowser.Model.Querying; - -namespace MediaBrowser.Model.Playlists -{ - public class PlaylistItemQuery - { - /// - /// Gets or sets the identifier. - /// - /// The identifier. - public string Id { get; set; } - - /// - /// Gets or sets the user identifier. - /// - /// The user identifier. - public string UserId { get; set; } - - /// - /// Gets or sets the start index. - /// - /// The start index. - public int? StartIndex { get; set; } - - /// - /// Gets or sets the limit. - /// - /// The limit. - public int? Limit { get; set; } - - /// - /// Gets or sets the fields. - /// - /// The fields. - public ItemFields[] Fields { get; set; } - } -} diff --git a/MediaBrowser.Model/Plugins/PluginInfo.cs b/MediaBrowser.Model/Plugins/PluginInfo.cs index 9ff9ea457f..c13f1a89f1 100644 --- a/MediaBrowser.Model/Plugins/PluginInfo.cs +++ b/MediaBrowser.Model/Plugins/PluginInfo.cs @@ -1,3 +1,4 @@ +#nullable disable namespace MediaBrowser.Model.Plugins { /// diff --git a/MediaBrowser.Model/Plugins/PluginPageInfo.cs b/MediaBrowser.Model/Plugins/PluginPageInfo.cs index eb6a1527d2..ca72e19ee1 100644 --- a/MediaBrowser.Model/Plugins/PluginPageInfo.cs +++ b/MediaBrowser.Model/Plugins/PluginPageInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Plugins diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 2b481ad7ed..f2e6d8ef32 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Providers diff --git a/MediaBrowser.Model/Providers/ExternalUrl.cs b/MediaBrowser.Model/Providers/ExternalUrl.cs index d4f4fa8403..9467a2b003 100644 --- a/MediaBrowser.Model/Providers/ExternalUrl.cs +++ b/MediaBrowser.Model/Providers/ExternalUrl.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Providers diff --git a/MediaBrowser.Model/Providers/ImageProviderInfo.cs b/MediaBrowser.Model/Providers/ImageProviderInfo.cs index a22ec3c079..c63a2ceda8 100644 --- a/MediaBrowser.Model/Providers/ImageProviderInfo.cs +++ b/MediaBrowser.Model/Providers/ImageProviderInfo.cs @@ -10,6 +10,12 @@ namespace MediaBrowser.Model.Providers /// public class ImageProviderInfo { + public ImageProviderInfo(string name, ImageType[] supportedImages) + { + Name = name; + SupportedImages = supportedImages; + } + /// /// Gets or sets the name. /// @@ -17,10 +23,5 @@ namespace MediaBrowser.Model.Providers public string Name { get; set; } public ImageType[] SupportedImages { get; set; } - - public ImageProviderInfo() - { - SupportedImages = Array.Empty(); - } } } diff --git a/MediaBrowser.Model/Providers/RemoteImageInfo.cs b/MediaBrowser.Model/Providers/RemoteImageInfo.cs index ee2b9d8fd1..78ab6c706c 100644 --- a/MediaBrowser.Model/Providers/RemoteImageInfo.cs +++ b/MediaBrowser.Model/Providers/RemoteImageInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Model/Providers/RemoteImageQuery.cs b/MediaBrowser.Model/Providers/RemoteImageQuery.cs index 2873c10038..b7fad87aba 100644 --- a/MediaBrowser.Model/Providers/RemoteImageQuery.cs +++ b/MediaBrowser.Model/Providers/RemoteImageQuery.cs @@ -6,7 +6,12 @@ namespace MediaBrowser.Model.Providers { public class RemoteImageQuery { - public string ProviderName { get; set; } + public RemoteImageQuery(string providerName) + { + ProviderName = providerName; + } + + public string ProviderName { get; } public ImageType? ImageType { get; set; } diff --git a/MediaBrowser.Model/Providers/RemoteImageResult.cs b/MediaBrowser.Model/Providers/RemoteImageResult.cs index 5ca00f7701..e6067ee6ef 100644 --- a/MediaBrowser.Model/Providers/RemoteImageResult.cs +++ b/MediaBrowser.Model/Providers/RemoteImageResult.cs @@ -1,3 +1,4 @@ +#nullable disable namespace MediaBrowser.Model.Providers { /// diff --git a/MediaBrowser.Model/Providers/RemoteSearchResult.cs b/MediaBrowser.Model/Providers/RemoteSearchResult.cs index 161e048214..c96eb0b59a 100644 --- a/MediaBrowser.Model/Providers/RemoteSearchResult.cs +++ b/MediaBrowser.Model/Providers/RemoteSearchResult.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -8,23 +9,34 @@ namespace MediaBrowser.Model.Providers { public class RemoteSearchResult : IHasProviderIds { + public RemoteSearchResult() + { + ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); + Artists = Array.Empty(); + } + /// /// Gets or sets the name. /// /// The name. public string Name { get; set; } + /// /// Gets or sets the provider ids. /// /// The provider ids. public Dictionary ProviderIds { get; set; } + /// /// Gets or sets the year. /// /// The year. public int? ProductionYear { get; set; } + public int? IndexNumber { get; set; } + public int? IndexNumberEnd { get; set; } + public int? ParentIndexNumber { get; set; } public DateTime? PremiereDate { get; set; } @@ -32,15 +44,13 @@ namespace MediaBrowser.Model.Providers public string ImageUrl { get; set; } public string SearchProviderName { get; set; } + public string Overview { get; set; } public RemoteSearchResult AlbumArtist { get; set; } + public RemoteSearchResult[] Artists { get; set; } - public RemoteSearchResult() - { - ProviderIds = new Dictionary(StringComparer.OrdinalIgnoreCase); - Artists = new RemoteSearchResult[] { }; - } + } } diff --git a/MediaBrowser.Model/Providers/RemoteSubtitleInfo.cs b/MediaBrowser.Model/Providers/RemoteSubtitleInfo.cs index 06f29df3f9..d9f7a852ca 100644 --- a/MediaBrowser.Model/Providers/RemoteSubtitleInfo.cs +++ b/MediaBrowser.Model/Providers/RemoteSubtitleInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Providers/SubtitleOptions.cs b/MediaBrowser.Model/Providers/SubtitleOptions.cs index 9e60492463..c073795704 100644 --- a/MediaBrowser.Model/Providers/SubtitleOptions.cs +++ b/MediaBrowser.Model/Providers/SubtitleOptions.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Providers/SubtitleProviderInfo.cs b/MediaBrowser.Model/Providers/SubtitleProviderInfo.cs index fca93d176e..ee25be4b6c 100644 --- a/MediaBrowser.Model/Providers/SubtitleProviderInfo.cs +++ b/MediaBrowser.Model/Providers/SubtitleProviderInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Providers diff --git a/MediaBrowser.Model/Querying/AllThemeMediaResult.cs b/MediaBrowser.Model/Querying/AllThemeMediaResult.cs index a264c6178c..6b503ba6ba 100644 --- a/MediaBrowser.Model/Querying/AllThemeMediaResult.cs +++ b/MediaBrowser.Model/Querying/AllThemeMediaResult.cs @@ -1,15 +1,10 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Querying { public class AllThemeMediaResult { - public ThemeMediaResult ThemeVideosResult { get; set; } - - public ThemeMediaResult ThemeSongsResult { get; set; } - - public ThemeMediaResult SoundtrackSongsResult { get; set; } - public AllThemeMediaResult() { ThemeVideosResult = new ThemeMediaResult(); @@ -18,5 +13,11 @@ namespace MediaBrowser.Model.Querying SoundtrackSongsResult = new ThemeMediaResult(); } + + public ThemeMediaResult ThemeVideosResult { get; set; } + + public ThemeMediaResult ThemeSongsResult { get; set; } + + public ThemeMediaResult SoundtrackSongsResult { get; set; } } } diff --git a/MediaBrowser.Model/Querying/EpisodeQuery.cs b/MediaBrowser.Model/Querying/EpisodeQuery.cs index 6fb4df676d..13b1a0dcbf 100644 --- a/MediaBrowser.Model/Querying/EpisodeQuery.cs +++ b/MediaBrowser.Model/Querying/EpisodeQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Querying/ItemCountsQuery.cs b/MediaBrowser.Model/Querying/ItemCountsQuery.cs deleted file mode 100644 index f113cf3808..0000000000 --- a/MediaBrowser.Model/Querying/ItemCountsQuery.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace MediaBrowser.Model.Querying -{ - /// - /// Class ItemCountsQuery. - /// - public class ItemCountsQuery - { - /// - /// Gets or sets the user id. - /// - /// The user id. - public string UserId { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is favorite. - /// - /// null if [is favorite] contains no value, true if [is favorite]; otherwise, false. - public bool? IsFavorite { get; set; } - } -} diff --git a/MediaBrowser.Model/Querying/ItemSortBy.cs b/MediaBrowser.Model/Querying/ItemSortBy.cs index 15b60ad84b..edf71c1a77 100644 --- a/MediaBrowser.Model/Querying/ItemSortBy.cs +++ b/MediaBrowser.Model/Querying/ItemSortBy.cs @@ -8,73 +8,99 @@ namespace MediaBrowser.Model.Querying public static class ItemSortBy { public const string AiredEpisodeOrder = "AiredEpisodeOrder"; + /// - /// The album + /// The album. /// public const string Album = "Album"; + /// - /// The album artist + /// The album artist. /// public const string AlbumArtist = "AlbumArtist"; + /// - /// The artist + /// The artist. /// public const string Artist = "Artist"; + /// - /// The date created + /// The date created. /// public const string DateCreated = "DateCreated"; + /// - /// The official rating + /// The official rating. /// public const string OfficialRating = "OfficialRating"; + /// - /// The date played + /// The date played. /// public const string DatePlayed = "DatePlayed"; + /// - /// The premiere date + /// The premiere date. /// public const string PremiereDate = "PremiereDate"; + public const string StartDate = "StartDate"; + /// - /// The sort name + /// The sort name. /// public const string SortName = "SortName"; + public const string Name = "Name"; + /// - /// The random + /// The random. /// public const string Random = "Random"; + /// - /// The runtime + /// The runtime. /// public const string Runtime = "Runtime"; + /// - /// The community rating + /// The community rating. /// public const string CommunityRating = "CommunityRating"; + /// - /// The production year + /// The production year. /// public const string ProductionYear = "ProductionYear"; + /// - /// The play count + /// The play count. /// public const string PlayCount = "PlayCount"; + /// - /// The critic rating + /// The critic rating. /// public const string CriticRating = "CriticRating"; + public const string IsFolder = "IsFolder"; + public const string IsUnplayed = "IsUnplayed"; + public const string IsPlayed = "IsPlayed"; + public const string SeriesSortName = "SeriesSortName"; + public const string VideoBitRate = "VideoBitRate"; + public const string AirTime = "AirTime"; + public const string Studio = "Studio"; + public const string IsFavoriteOrLiked = "IsFavoriteOrLiked"; + public const string DateLastContentAdded = "DateLastContentAdded"; + public const string SeriesDatePlayed = "SeriesDatePlayed"; } } diff --git a/MediaBrowser.Model/Querying/LatestItemsQuery.cs b/MediaBrowser.Model/Querying/LatestItemsQuery.cs index 84e29e76a9..7954ef4b43 100644 --- a/MediaBrowser.Model/Querying/LatestItemsQuery.cs +++ b/MediaBrowser.Model/Querying/LatestItemsQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -7,8 +8,13 @@ namespace MediaBrowser.Model.Querying { public class LatestItemsQuery { + public LatestItemsQuery() + { + EnableImageTypes = Array.Empty(); + } + /// - /// The user to localize search results for + /// The user to localize search results for. /// /// The user id. public Guid UserId { get; set; } @@ -26,13 +32,13 @@ namespace MediaBrowser.Model.Querying public int? StartIndex { get; set; } /// - /// The maximum number of items to return + /// The maximum number of items to return. /// /// The limit. public int? Limit { get; set; } /// - /// Fields to return within the items, in addition to basic information + /// Fields to return within the items, in addition to basic information. /// /// The fields. public ItemFields[] Fields { get; set; } @@ -54,25 +60,23 @@ namespace MediaBrowser.Model.Querying /// /// true if [group items]; otherwise, false. public bool GroupItems { get; set; } + /// /// Gets or sets a value indicating whether [enable images]. /// /// null if [enable images] contains no value, true if [enable images]; otherwise, false. public bool? EnableImages { get; set; } + /// /// Gets or sets the image type limit. /// /// The image type limit. public int? ImageTypeLimit { get; set; } + /// /// Gets or sets the enable image types. /// /// The enable image types. public ImageType[] EnableImageTypes { get; set; } - - public LatestItemsQuery() - { - EnableImageTypes = new ImageType[] { }; - } } } diff --git a/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs b/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs index 93de0a8cd1..1c8875890a 100644 --- a/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs +++ b/MediaBrowser.Model/Querying/MovieRecommendationQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Querying/NextUpQuery.cs b/MediaBrowser.Model/Querying/NextUpQuery.cs index 1543aea16f..0df86cb22d 100644 --- a/MediaBrowser.Model/Querying/NextUpQuery.cs +++ b/MediaBrowser.Model/Querying/NextUpQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Querying/QueryFilters.cs b/MediaBrowser.Model/Querying/QueryFilters.cs index 8d879c1748..e04208f766 100644 --- a/MediaBrowser.Model/Querying/QueryFilters.cs +++ b/MediaBrowser.Model/Querying/QueryFilters.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Querying/QueryResult.cs b/MediaBrowser.Model/Querying/QueryResult.cs index 266f1c7e65..42586243da 100644 --- a/MediaBrowser.Model/Querying/QueryResult.cs +++ b/MediaBrowser.Model/Querying/QueryResult.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Querying/ThemeMediaResult.cs b/MediaBrowser.Model/Querying/ThemeMediaResult.cs index bae954d78e..5afedeeaf7 100644 --- a/MediaBrowser.Model/Querying/ThemeMediaResult.cs +++ b/MediaBrowser.Model/Querying/ThemeMediaResult.cs @@ -4,7 +4,7 @@ using MediaBrowser.Model.Dto; namespace MediaBrowser.Model.Querying { /// - /// Class ThemeMediaResult + /// Class ThemeMediaResult. /// public class ThemeMediaResult : QueryResult { diff --git a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs index 123d0fad23..ed1aa7ac6d 100644 --- a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs +++ b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using MediaBrowser.Model.Entities; diff --git a/MediaBrowser.Model/Search/SearchHint.cs b/MediaBrowser.Model/Search/SearchHint.cs index 6e52314fa9..c7a721df6e 100644 --- a/MediaBrowser.Model/Search/SearchHint.cs +++ b/MediaBrowser.Model/Search/SearchHint.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Search/SearchHintResult.cs b/MediaBrowser.Model/Search/SearchHintResult.cs index 3c4fbec9e8..92ba4139ea 100644 --- a/MediaBrowser.Model/Search/SearchHintResult.cs +++ b/MediaBrowser.Model/Search/SearchHintResult.cs @@ -1,3 +1,4 @@ +#nullable disable namespace MediaBrowser.Model.Search { /// diff --git a/MediaBrowser.Model/Search/SearchQuery.cs b/MediaBrowser.Model/Search/SearchQuery.cs index 8a018312e0..4470f1ad97 100644 --- a/MediaBrowser.Model/Search/SearchQuery.cs +++ b/MediaBrowser.Model/Search/SearchQuery.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Serialization/IJsonSerializer.cs b/MediaBrowser.Model/Serialization/IJsonSerializer.cs index 6223bb5598..09b6ff9b5a 100644 --- a/MediaBrowser.Model/Serialization/IJsonSerializer.cs +++ b/MediaBrowser.Model/Serialization/IJsonSerializer.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Serialization/IXmlSerializer.cs b/MediaBrowser.Model/Serialization/IXmlSerializer.cs index 1edd98fadd..16d126ac7c 100644 --- a/MediaBrowser.Model/Serialization/IXmlSerializer.cs +++ b/MediaBrowser.Model/Serialization/IXmlSerializer.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Services/ApiMemberAttribute.cs b/MediaBrowser.Model/Services/ApiMemberAttribute.cs index 8e50836f4d..7c23eee448 100644 --- a/MediaBrowser.Model/Services/ApiMemberAttribute.cs +++ b/MediaBrowser.Model/Services/ApiMemberAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace MediaBrowser.Model.Services diff --git a/MediaBrowser.Model/Services/IHasRequestFilter.cs b/MediaBrowser.Model/Services/IHasRequestFilter.cs index 3d2e9c0dcf..332ba113c7 100644 --- a/MediaBrowser.Model/Services/IHasRequestFilter.cs +++ b/MediaBrowser.Model/Services/IHasRequestFilter.cs @@ -7,18 +7,18 @@ namespace MediaBrowser.Model.Services public interface IHasRequestFilter { /// - /// Order in which Request Filters are executed. + /// Gets the order in which Request Filters are executed. /// <0 Executed before global request filters - /// >0 Executed after global request filters + /// >0 Executed after global request filters. /// int Priority { get; } /// /// The request filter is executed before the service. /// - /// The http request wrapper - /// The http response wrapper - /// The request DTO + /// The http request wrapper. + /// The http response wrapper. + /// The request DTO. void RequestFilter(IRequest req, HttpResponse res, object requestDto); } } diff --git a/MediaBrowser.Model/Services/IHttpRequest.cs b/MediaBrowser.Model/Services/IHttpRequest.cs index 4dccd2d686..3ea65195cd 100644 --- a/MediaBrowser.Model/Services/IHttpRequest.cs +++ b/MediaBrowser.Model/Services/IHttpRequest.cs @@ -5,12 +5,12 @@ namespace MediaBrowser.Model.Services public interface IHttpRequest : IRequest { /// - /// The HTTP Verb + /// Gets the HTTP Verb. /// string HttpMethod { get; } /// - /// The value of the Accept HTTP Request Header + /// Gets the value of the Accept HTTP Request Header. /// string Accept { get; } } diff --git a/MediaBrowser.Model/Services/IHttpResult.cs b/MediaBrowser.Model/Services/IHttpResult.cs index b153f15ec3..abc581d8e2 100644 --- a/MediaBrowser.Model/Services/IHttpResult.cs +++ b/MediaBrowser.Model/Services/IHttpResult.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System.Net; @@ -7,27 +8,27 @@ namespace MediaBrowser.Model.Services public interface IHttpResult : IHasHeaders { /// - /// The HTTP Response Status + /// The HTTP Response Status. /// int Status { get; set; } /// - /// The HTTP Response Status Code + /// The HTTP Response Status Code. /// HttpStatusCode StatusCode { get; set; } /// - /// The HTTP Response ContentType + /// The HTTP Response ContentType. /// string ContentType { get; set; } /// - /// Response DTO + /// Response DTO. /// object Response { get; set; } /// - /// Holds the request call context + /// Holds the request call context. /// IRequest RequestContext { get; set; } } diff --git a/MediaBrowser.Model/Services/IRequest.cs b/MediaBrowser.Model/Services/IRequest.cs index 3f4edced61..f413f1e177 100644 --- a/MediaBrowser.Model/Services/IRequest.cs +++ b/MediaBrowser.Model/Services/IRequest.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Services/QueryParamCollection.cs b/MediaBrowser.Model/Services/QueryParamCollection.cs index 19e9e53e76..d07ff15482 100644 --- a/MediaBrowser.Model/Services/QueryParamCollection.cs +++ b/MediaBrowser.Model/Services/QueryParamCollection.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -19,11 +20,6 @@ namespace MediaBrowser.Model.Services return StringComparison.OrdinalIgnoreCase; } - private static StringComparer GetStringComparer() - { - return StringComparer.OrdinalIgnoreCase; - } - /// /// Adds a new query parameter. /// diff --git a/MediaBrowser.Model/Services/RouteAttribute.cs b/MediaBrowser.Model/Services/RouteAttribute.cs index 197ba05e58..162576aa7e 100644 --- a/MediaBrowser.Model/Services/RouteAttribute.cs +++ b/MediaBrowser.Model/Services/RouteAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Session/BrowseRequest.cs b/MediaBrowser.Model/Session/BrowseRequest.cs index f485d680e2..1c997d5846 100644 --- a/MediaBrowser.Model/Session/BrowseRequest.cs +++ b/MediaBrowser.Model/Session/BrowseRequest.cs @@ -1,3 +1,4 @@ +#nullable disable namespace MediaBrowser.Model.Session { /// diff --git a/MediaBrowser.Model/Session/ClientCapabilities.cs b/MediaBrowser.Model/Session/ClientCapabilities.cs index 5da4998e84..51db66d212 100644 --- a/MediaBrowser.Model/Session/ClientCapabilities.cs +++ b/MediaBrowser.Model/Session/ClientCapabilities.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Session/GeneralCommand.cs b/MediaBrowser.Model/Session/GeneralCommand.cs index 980e1f88b2..9794bd2929 100644 --- a/MediaBrowser.Model/Session/GeneralCommand.cs +++ b/MediaBrowser.Model/Session/GeneralCommand.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Session/MessageCommand.cs b/MediaBrowser.Model/Session/MessageCommand.cs index 473a7bccc9..09abfbb3f2 100644 --- a/MediaBrowser.Model/Session/MessageCommand.cs +++ b/MediaBrowser.Model/Session/MessageCommand.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Session diff --git a/MediaBrowser.Model/Session/PlayRequest.cs b/MediaBrowser.Model/Session/PlayRequest.cs index bdb2b24394..62b68b49ea 100644 --- a/MediaBrowser.Model/Session/PlayRequest.cs +++ b/MediaBrowser.Model/Session/PlayRequest.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs index 5687ba84bb..6b4cfe4f0d 100644 --- a/MediaBrowser.Model/Session/PlaybackProgressInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackProgressInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Session/PlaybackStopInfo.cs b/MediaBrowser.Model/Session/PlaybackStopInfo.cs index f8cfacc201..b0827ac99c 100644 --- a/MediaBrowser.Model/Session/PlaybackStopInfo.cs +++ b/MediaBrowser.Model/Session/PlaybackStopInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Session/PlayerStateInfo.cs b/MediaBrowser.Model/Session/PlayerStateInfo.cs index 0f99568739..0f10605ea1 100644 --- a/MediaBrowser.Model/Session/PlayerStateInfo.cs +++ b/MediaBrowser.Model/Session/PlayerStateInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Session diff --git a/MediaBrowser.Model/Session/PlaystateRequest.cs b/MediaBrowser.Model/Session/PlaystateRequest.cs index 493a8063ad..ba2c024b76 100644 --- a/MediaBrowser.Model/Session/PlaystateRequest.cs +++ b/MediaBrowser.Model/Session/PlaystateRequest.cs @@ -12,6 +12,6 @@ namespace MediaBrowser.Model.Session /// Gets or sets the controlling user identifier. /// /// The controlling user identifier. - public string ControllingUserId { get; set; } + public string? ControllingUserId { get; set; } } } diff --git a/MediaBrowser.Model/Session/SessionUserInfo.cs b/MediaBrowser.Model/Session/SessionUserInfo.cs index 42a56b92b9..4d6f35efc7 100644 --- a/MediaBrowser.Model/Session/SessionUserInfo.cs +++ b/MediaBrowser.Model/Session/SessionUserInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace MediaBrowser.Model.Session @@ -12,6 +13,7 @@ namespace MediaBrowser.Model.Session /// /// The user identifier. public Guid UserId { get; set; } + /// /// Gets or sets the name of the user. /// diff --git a/MediaBrowser.Model/Session/TranscodingInfo.cs b/MediaBrowser.Model/Session/TranscodingInfo.cs index 8f4e688f09..d6dc83413b 100644 --- a/MediaBrowser.Model/Session/TranscodingInfo.cs +++ b/MediaBrowser.Model/Session/TranscodingInfo.cs @@ -1,5 +1,8 @@ +#nullable disable #pragma warning disable CS1591 +using System; + namespace MediaBrowser.Model.Session { public class TranscodingInfo @@ -22,7 +25,7 @@ namespace MediaBrowser.Model.Session public TranscodingInfo() { - TranscodeReasons = new TranscodeReason[] { }; + TranscodeReasons = Array.Empty(); } } diff --git a/MediaBrowser.Model/Session/UserDataChangeInfo.cs b/MediaBrowser.Model/Session/UserDataChangeInfo.cs index 0872eb4b11..0fd24edccd 100644 --- a/MediaBrowser.Model/Session/UserDataChangeInfo.cs +++ b/MediaBrowser.Model/Session/UserDataChangeInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using MediaBrowser.Model.Dto; namespace MediaBrowser.Model.Session diff --git a/MediaBrowser.Model/Sync/SyncJob.cs b/MediaBrowser.Model/Sync/SyncJob.cs index 30bf27f381..3cc9ff7267 100644 --- a/MediaBrowser.Model/Sync/SyncJob.cs +++ b/MediaBrowser.Model/Sync/SyncJob.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Sync/SyncTarget.cs b/MediaBrowser.Model/Sync/SyncTarget.cs index 20a0c8cc77..9e6bbbc009 100644 --- a/MediaBrowser.Model/Sync/SyncTarget.cs +++ b/MediaBrowser.Model/Sync/SyncTarget.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Sync diff --git a/MediaBrowser.Model/System/LogFile.cs b/MediaBrowser.Model/System/LogFile.cs index a2b7016648..aec910c92c 100644 --- a/MediaBrowser.Model/System/LogFile.cs +++ b/MediaBrowser.Model/System/LogFile.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/System/PublicSystemInfo.cs b/MediaBrowser.Model/System/PublicSystemInfo.cs index 1775470b54..b6196a43fc 100644 --- a/MediaBrowser.Model/System/PublicSystemInfo.cs +++ b/MediaBrowser.Model/System/PublicSystemInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.System diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index cfa7684c91..7582cb7485 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; @@ -34,7 +35,6 @@ namespace MediaBrowser.Model.System /// The display name of the operating system. public string OperatingSystemDisplayName { get; set; } - /// /// Get or sets the package name. /// diff --git a/MediaBrowser.Model/System/WakeOnLanInfo.cs b/MediaBrowser.Model/System/WakeOnLanInfo.cs index 534ad19ecc..b2cbe737d1 100644 --- a/MediaBrowser.Model/System/WakeOnLanInfo.cs +++ b/MediaBrowser.Model/System/WakeOnLanInfo.cs @@ -7,36 +7,21 @@ namespace MediaBrowser.Model.System /// public class WakeOnLanInfo { - /// - /// Returns the MAC address of the device. - /// - /// The MAC address. - public string MacAddress { get; set; } - - /// - /// Returns the wake-on-LAN port. - /// - /// The wake-on-LAN port. - public int Port { get; set; } - /// /// Initializes a new instance of the class. /// /// The MAC address. - public WakeOnLanInfo(PhysicalAddress macAddress) + public WakeOnLanInfo(PhysicalAddress macAddress) : this(macAddress.ToString()) { - MacAddress = macAddress.ToString(); - Port = 9; } /// /// Initializes a new instance of the class. /// /// The MAC address. - public WakeOnLanInfo(string macAddress) + public WakeOnLanInfo(string macAddress) : this() { MacAddress = macAddress; - Port = 9; } /// @@ -46,5 +31,17 @@ namespace MediaBrowser.Model.System { Port = 9; } + + /// + /// Gets the MAC address of the device. + /// + /// The MAC address. + public string? MacAddress { get; set; } + + /// + /// Gets or sets the wake-on-LAN port. + /// + /// The wake-on-LAN port. + public int Port { get; set; } } } diff --git a/MediaBrowser.Model/Tasks/IScheduledTask.cs b/MediaBrowser.Model/Tasks/IScheduledTask.cs index ed160e1762..bf87088e45 100644 --- a/MediaBrowser.Model/Tasks/IScheduledTask.cs +++ b/MediaBrowser.Model/Tasks/IScheduledTask.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Collections.Generic; using System.Threading; @@ -8,16 +6,19 @@ using System.Threading.Tasks; namespace MediaBrowser.Model.Tasks { /// - /// Interface IScheduledTaskWorker + /// Interface IScheduledTaskWorker. /// public interface IScheduledTask { /// - /// Gets the name of the task + /// Gets the name of the task. /// /// The name. string Name { get; } + /// + /// Gets the key of the task. + /// string Key { get; } /// @@ -33,7 +34,7 @@ namespace MediaBrowser.Model.Tasks string Category { get; } /// - /// Executes the task + /// Executes the task. /// /// The cancellation token. /// The progress. diff --git a/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs index 4dd1bb5d04..c79d7fe75d 100644 --- a/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs +++ b/MediaBrowser.Model/Tasks/IScheduledTaskWorker.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using MediaBrowser.Model.Events; diff --git a/MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs b/MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs index ca0743ccae..9063903ae0 100644 --- a/MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs +++ b/MediaBrowser.Model/Tasks/ScheduledTaskHelpers.cs @@ -14,9 +14,7 @@ namespace MediaBrowser.Model.Tasks { var isHidden = false; - var configurableTask = task.ScheduledTask as IConfigurableScheduledTask; - - if (configurableTask != null) + if (task.ScheduledTask is IConfigurableScheduledTask configurableTask) { isHidden = configurableTask.IsHidden; } diff --git a/MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs b/MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs index cc6c2b62b3..48950667e6 100644 --- a/MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs +++ b/MediaBrowser.Model/Tasks/TaskCompletionEventArgs.cs @@ -6,8 +6,14 @@ namespace MediaBrowser.Model.Tasks { public class TaskCompletionEventArgs : EventArgs { - public IScheduledTaskWorker Task { get; set; } + public TaskCompletionEventArgs(IScheduledTaskWorker task, TaskResult result) + { + Task = task; + Result = result; + } - public TaskResult Result { get; set; } + public IScheduledTaskWorker Task { get; } + + public TaskResult Result { get; } } } diff --git a/MediaBrowser.Model/Tasks/TaskInfo.cs b/MediaBrowser.Model/Tasks/TaskInfo.cs index 5144c035ab..77100dfe76 100644 --- a/MediaBrowser.Model/Tasks/TaskInfo.cs +++ b/MediaBrowser.Model/Tasks/TaskInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace MediaBrowser.Model.Tasks diff --git a/MediaBrowser.Model/Tasks/TaskResult.cs b/MediaBrowser.Model/Tasks/TaskResult.cs index c6f92e7ed5..31001aeb22 100644 --- a/MediaBrowser.Model/Tasks/TaskResult.cs +++ b/MediaBrowser.Model/Tasks/TaskResult.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace MediaBrowser.Model.Tasks diff --git a/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs b/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs index 699e0ea3a8..5aeaffc2b3 100644 --- a/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs +++ b/MediaBrowser.Model/Tasks/TaskTriggerInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Updates/CheckForUpdateResult.cs b/MediaBrowser.Model/Updates/CheckForUpdateResult.cs index be1b082238..9c59a7c886 100644 --- a/MediaBrowser.Model/Updates/CheckForUpdateResult.cs +++ b/MediaBrowser.Model/Updates/CheckForUpdateResult.cs @@ -1,3 +1,4 @@ +#nullable disable namespace MediaBrowser.Model.Updates { /// diff --git a/MediaBrowser.Model/Updates/InstallationInfo.cs b/MediaBrowser.Model/Updates/InstallationInfo.cs index 42c2105f54..4651a4169d 100644 --- a/MediaBrowser.Model/Updates/InstallationInfo.cs +++ b/MediaBrowser.Model/Updates/InstallationInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace MediaBrowser.Model.Updates diff --git a/MediaBrowser.Model/Updates/PackageInfo.cs b/MediaBrowser.Model/Updates/PackageInfo.cs index abbe91eff6..b5a5068e7b 100644 --- a/MediaBrowser.Model/Updates/PackageInfo.cs +++ b/MediaBrowser.Model/Updates/PackageInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; diff --git a/MediaBrowser.Model/Updates/PackageVersionInfo.cs b/MediaBrowser.Model/Updates/PackageVersionInfo.cs index 3eef965dd6..9ef67966bc 100644 --- a/MediaBrowser.Model/Updates/PackageVersionInfo.cs +++ b/MediaBrowser.Model/Updates/PackageVersionInfo.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Users/ForgotPasswordResult.cs b/MediaBrowser.Model/Users/ForgotPasswordResult.cs index 368c642e8f..6bb13d4c9d 100644 --- a/MediaBrowser.Model/Users/ForgotPasswordResult.cs +++ b/MediaBrowser.Model/Users/ForgotPasswordResult.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Users/PinRedeemResult.cs b/MediaBrowser.Model/Users/PinRedeemResult.cs index ab868cad43..7e4553bac8 100644 --- a/MediaBrowser.Model/Users/PinRedeemResult.cs +++ b/MediaBrowser.Model/Users/PinRedeemResult.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 namespace MediaBrowser.Model.Users diff --git a/MediaBrowser.Model/Users/UserAction.cs b/MediaBrowser.Model/Users/UserAction.cs index f6bb6451b6..36b8e6ee52 100644 --- a/MediaBrowser.Model/Users/UserAction.cs +++ b/MediaBrowser.Model/Users/UserAction.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs index ae2b3fd4e9..9f85022ef5 100644 --- a/MediaBrowser.Model/Users/UserPolicy.cs +++ b/MediaBrowser.Model/Users/UserPolicy.cs @@ -1,3 +1,4 @@ +#nullable disable #pragma warning disable CS1591 using System; diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs index 6ef0e44a2b..48e1c94adc 100644 --- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs +++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs @@ -230,7 +230,9 @@ namespace MediaBrowser.Providers.Manager /// The result. /// The cancellation token. /// Task. - private async Task RefreshFromProvider(BaseItem item, LibraryOptions libraryOptions, + private async Task RefreshFromProvider( + BaseItem item, + LibraryOptions libraryOptions, IRemoteImageProvider provider, ImageRefreshOptions refreshOptions, TypeOptions savedOptions, @@ -256,20 +258,24 @@ namespace MediaBrowser.Providers.Manager _logger.LogDebug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name); - var images = await _providerManager.GetAvailableRemoteImages(item, new RemoteImageQuery - { - ProviderName = provider.Name, - IncludeAllLanguages = false, - IncludeDisabledProviders = false, - - }, cancellationToken).ConfigureAwait(false); + var images = await _providerManager.GetAvailableRemoteImages( + item, + new RemoteImageQuery(provider.Name) + { + IncludeAllLanguages = false, + IncludeDisabledProviders = false, + }, + cancellationToken).ConfigureAwait(false); var list = images.ToList(); int minWidth; foreach (var imageType in _singularImages) { - if (!IsEnabled(savedOptions, imageType, item)) continue; + if (!IsEnabled(savedOptions, imageType, item)) + { + continue; + } if (!HasImage(item, imageType) || (refreshOptions.IsReplacingImage(imageType) && !downloadedImages.Contains(imageType))) { diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 7125f34c55..bf3677850a 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -264,11 +264,7 @@ namespace MediaBrowser.Providers.Manager /// IEnumerable{IImageProvider}. public IEnumerable GetRemoteImageProviderInfo(BaseItem item) { - return GetRemoteImageProviders(item, true).Select(i => new ImageProviderInfo - { - Name = i.Name, - SupportedImages = i.GetSupportedImages(item).ToArray() - }); + return GetRemoteImageProviders(item, true).Select(i => new ImageProviderInfo(i.Name, i.GetSupportedImages(item).ToArray())); } public IEnumerable GetImageProviders(BaseItem item, ImageRefreshOptions refreshOptions) From 2fcbc2a5b804e8d426dfd014560291d2399ab799 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 5 Apr 2020 21:19:04 +0200 Subject: [PATCH 103/517] Enable nullabe reference types for Emby.Drawing and Jellyfin.Drawing.Skia --- Emby.Dlna/ConfigurationExtension.cs | 1 + Emby.Drawing/Emby.Drawing.csproj | 1 + Emby.Drawing/ImageProcessor.cs | 22 +++---------- .../Data/SqliteItemRepository.cs | 9 +++++- .../Jellyfin.Drawing.Skia.csproj | 1 + .../PlayedIndicatorDrawer.cs | 13 +++----- Jellyfin.Drawing.Skia/SkiaEncoder.cs | 32 +++++++++---------- Jellyfin.Drawing.Skia/StripCollageBuilder.cs | 10 +++--- .../UnplayedCountIndicator.cs | 4 +-- .../Extensions/ShuffleExtensions.cs | 2 ++ 10 files changed, 45 insertions(+), 50 deletions(-) diff --git a/Emby.Dlna/ConfigurationExtension.cs b/Emby.Dlna/ConfigurationExtension.cs index e224d10bd3..dba9019677 100644 --- a/Emby.Dlna/ConfigurationExtension.cs +++ b/Emby.Dlna/ConfigurationExtension.cs @@ -1,3 +1,4 @@ +#nullable enable #pragma warning disable CS1591 using System.Collections.Generic; diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index b7090b2629..b17fff751b 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -5,6 +5,7 @@ false true true + enable diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index eca4b56eb9..3d6bcc045d 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -121,11 +121,6 @@ namespace Emby.Drawing /// public async Task<(string path, string mimeType, DateTime dateModified)> ProcessImage(ImageProcessingOptions options) { - if (options == null) - { - throw new ArgumentNullException(nameof(options)); - } - var libraryManager = _libraryManager(); ItemImageInfo originalImage = options.Image; @@ -351,19 +346,12 @@ namespace Emby.Drawing /// public string GetImageCacheTag(BaseItem item, ChapterInfo chapter) { - try + return GetImageCacheTag(item, new ItemImageInfo { - return GetImageCacheTag(item, new ItemImageInfo - { - Path = chapter.ImagePath, - Type = ImageType.Chapter, - DateModified = chapter.ImageDateModified - }); - } - catch - { - return null; - } + Path = chapter.ImagePath, + Type = ImageType.Chapter, + DateModified = chapter.ImageDateModified + }); } private async Task<(string path, DateTime dateModified)> GetSupportedImage(string originalImagePath, DateTime dateModified) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 46c6d55200..d3b3f7b7af 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -1991,7 +1991,14 @@ namespace Emby.Server.Implementations.Data if (!string.IsNullOrEmpty(chapter.ImagePath)) { - chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter); + try + { + chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter); + } + catch + { + + } } } diff --git a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj index d0a99e1e28..e4b4c058ec 100644 --- a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj +++ b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj @@ -5,6 +5,7 @@ false true true + enable diff --git a/Jellyfin.Drawing.Skia/PlayedIndicatorDrawer.cs b/Jellyfin.Drawing.Skia/PlayedIndicatorDrawer.cs index 5084fd211c..7eed5f4f79 100644 --- a/Jellyfin.Drawing.Skia/PlayedIndicatorDrawer.cs +++ b/Jellyfin.Drawing.Skia/PlayedIndicatorDrawer.cs @@ -26,7 +26,7 @@ namespace Jellyfin.Drawing.Skia { paint.Color = SKColor.Parse("#CC00A4DC"); paint.Style = SKPaintStyle.Fill; - canvas.DrawCircle((float)x, OffsetFromTopRightCorner, 20, paint); + canvas.DrawCircle(x, OffsetFromTopRightCorner, 20, paint); } using (var paint = new SKPaint()) @@ -39,16 +39,13 @@ namespace Jellyfin.Drawing.Skia // or: // var emojiChar = 0x1F680; - var text = "✔️"; - var emojiChar = StringUtilities.GetUnicodeCharacterCode(text, SKTextEncoding.Utf32); + const string Text = "✔️"; + var emojiChar = StringUtilities.GetUnicodeCharacterCode(Text, SKTextEncoding.Utf32); // ask the font manager for a font with that character - var fontManager = SKFontManager.Default; - var emojiTypeface = fontManager.MatchCharacter(emojiChar); + paint.Typeface = SKFontManager.Default.MatchCharacter(emojiChar); - paint.Typeface = emojiTypeface; - - canvas.DrawText(text, (float)x - 20, OffsetFromTopRightCorner + 12, paint); + canvas.DrawText(Text, (float)x - 20, OffsetFromTopRightCorner + 12, paint); } } } diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs index a67118f188..723c523405 100644 --- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs +++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs @@ -205,11 +205,6 @@ namespace Jellyfin.Drawing.Skia /// The file at the specified path could not be used to generate a codec. public ImageDimensions GetImageSize(string path) { - if (path == null) - { - throw new ArgumentNullException(nameof(path)); - } - if (!File.Exists(path)) { throw new FileNotFoundException("File not found", path); @@ -297,7 +292,7 @@ namespace Jellyfin.Drawing.Skia /// The orientation of the image. /// The detected origin of the image. /// The resulting bitmap of the image. - internal SKBitmap Decode(string path, bool forceCleanBitmap, ImageOrientation? orientation, out SKEncodedOrigin origin) + internal SKBitmap? Decode(string path, bool forceCleanBitmap, ImageOrientation? orientation, out SKEncodedOrigin origin) { if (!File.Exists(path)) { @@ -348,12 +343,17 @@ namespace Jellyfin.Drawing.Skia return resultBitmap; } - private SKBitmap GetBitmap(string path, bool cropWhitespace, bool forceAnalyzeBitmap, ImageOrientation? orientation, out SKEncodedOrigin origin) + private SKBitmap? GetBitmap(string path, bool cropWhitespace, bool forceAnalyzeBitmap, ImageOrientation? orientation, out SKEncodedOrigin origin) { if (cropWhitespace) { using (var bitmap = Decode(path, forceAnalyzeBitmap, orientation, out origin)) { + if (bitmap == null) + { + return null; + } + return CropWhiteSpace(bitmap); } } @@ -361,13 +361,11 @@ namespace Jellyfin.Drawing.Skia return Decode(path, forceAnalyzeBitmap, orientation, out origin); } - private SKBitmap GetBitmap(string path, bool cropWhitespace, bool autoOrient, ImageOrientation? orientation) + private SKBitmap? GetBitmap(string path, bool cropWhitespace, bool autoOrient, ImageOrientation? orientation) { - SKEncodedOrigin origin; - if (autoOrient) { - var bitmap = GetBitmap(path, cropWhitespace, true, orientation, out origin); + var bitmap = GetBitmap(path, cropWhitespace, true, orientation, out var origin); if (bitmap != null && origin != SKEncodedOrigin.TopLeft) { @@ -380,7 +378,7 @@ namespace Jellyfin.Drawing.Skia return bitmap; } - return GetBitmap(path, cropWhitespace, false, orientation, out origin); + return GetBitmap(path, cropWhitespace, false, orientation, out _); } private SKBitmap OrientImage(SKBitmap bitmap, SKEncodedOrigin origin) @@ -517,14 +515,14 @@ namespace Jellyfin.Drawing.Skia /// public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat) { - if (string.IsNullOrWhiteSpace(inputPath)) + if (inputPath.Length == 0) { - throw new ArgumentNullException(nameof(inputPath)); + throw new ArgumentException("String can't be empty.", nameof(inputPath)); } - if (string.IsNullOrWhiteSpace(inputPath)) + if (outputPath.Length == 0) { - throw new ArgumentNullException(nameof(outputPath)); + throw new ArgumentException("String can't be empty.", nameof(outputPath)); } var skiaOutputFormat = GetImageFormat(selectedOutputFormat); @@ -538,7 +536,7 @@ namespace Jellyfin.Drawing.Skia { if (bitmap == null) { - throw new ArgumentOutOfRangeException($"Skia unable to read image {inputPath}"); + throw new InvalidDataException($"Skia unable to read image {inputPath}"); } var originalImageSize = new ImageDimensions(bitmap.Width, bitmap.Height); diff --git a/Jellyfin.Drawing.Skia/StripCollageBuilder.cs b/Jellyfin.Drawing.Skia/StripCollageBuilder.cs index 0735ef194a..61bef90ec5 100644 --- a/Jellyfin.Drawing.Skia/StripCollageBuilder.cs +++ b/Jellyfin.Drawing.Skia/StripCollageBuilder.cs @@ -120,13 +120,13 @@ namespace Jellyfin.Drawing.Skia } // resize to the same aspect as the original - int iWidth = (int)Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height); + int iWidth = Math.Abs(iHeight * currentBitmap.Width / currentBitmap.Height); using (var resizeBitmap = new SKBitmap(iWidth, iHeight, currentBitmap.ColorType, currentBitmap.AlphaType)) { currentBitmap.ScalePixels(resizeBitmap, SKFilterQuality.High); // crop image - int ix = (int)Math.Abs((iWidth - iSlice) / 2); + int ix = Math.Abs((iWidth - iSlice) / 2); using (var image = SKImage.FromBitmap(resizeBitmap)) using (var subset = image.Subset(SKRectI.Create(ix, 0, iSlice, iHeight))) { @@ -141,10 +141,10 @@ namespace Jellyfin.Drawing.Skia return bitmap; } - private SKBitmap GetNextValidImage(string[] paths, int currentIndex, out int newIndex) + private SKBitmap? GetNextValidImage(string[] paths, int currentIndex, out int newIndex) { var imagesTested = new Dictionary(); - SKBitmap bitmap = null; + SKBitmap? bitmap = null; while (imagesTested.Count < paths.Length) { @@ -153,7 +153,7 @@ namespace Jellyfin.Drawing.Skia currentIndex = 0; } - bitmap = _skiaEncoder.Decode(paths[currentIndex], false, null, out var origin); + bitmap = _skiaEncoder.Decode(paths[currentIndex], false, null, out _); imagesTested[currentIndex] = 0; diff --git a/Jellyfin.Drawing.Skia/UnplayedCountIndicator.cs b/Jellyfin.Drawing.Skia/UnplayedCountIndicator.cs index a10fff9dfe..cf3dbde2c0 100644 --- a/Jellyfin.Drawing.Skia/UnplayedCountIndicator.cs +++ b/Jellyfin.Drawing.Skia/UnplayedCountIndicator.cs @@ -32,7 +32,7 @@ namespace Jellyfin.Drawing.Skia { paint.Color = SKColor.Parse("#CC00A4DC"); paint.Style = SKPaintStyle.Fill; - canvas.DrawCircle((float)x, OffsetFromTopRightCorner, 20, paint); + canvas.DrawCircle(x, OffsetFromTopRightCorner, 20, paint); } using (var paint = new SKPaint()) @@ -61,7 +61,7 @@ namespace Jellyfin.Drawing.Skia paint.TextSize = 18; } - canvas.DrawText(text, (float)x, y, paint); + canvas.DrawText(text, x, y, paint); } } } diff --git a/MediaBrowser.Common/Extensions/ShuffleExtensions.cs b/MediaBrowser.Common/Extensions/ShuffleExtensions.cs index 0432f36b57..459bec1105 100644 --- a/MediaBrowser.Common/Extensions/ShuffleExtensions.cs +++ b/MediaBrowser.Common/Extensions/ShuffleExtensions.cs @@ -1,3 +1,5 @@ +#nullable enable + using System; using System.Collections.Generic; From 410a322fe22302eb3c8a37ea38bbe1d7e9d12aff Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 5 Apr 2020 23:30:57 -0400 Subject: [PATCH 104/517] Add CanConnectWithHttps to interface --- Emby.Server.Implementations/ApplicationHost.cs | 5 +---- MediaBrowser.Controller/IServerApplicationHost.cs | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8158b45592..9cb7471717 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1449,10 +1449,7 @@ namespace Emby.Server.Implementations /// public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.Configuration.EnableHttps; - /// - /// Gets a value indicating whether a client can connect to the server over HTTPS, either directly or via a - /// reverse proxy. - /// + /// public bool CanConnectWithHttps => ListenWithHttps || ServerConfigurationManager.Configuration.IsBehindProxy; public async Task GetLocalApiUrl(CancellationToken cancellationToken) diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index d999f76dbf..7742279f7a 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -43,6 +43,12 @@ namespace MediaBrowser.Controller /// bool ListenWithHttps { get; } + /// + /// Gets a value indicating whether a client can connect to the server over HTTPS, either directly or via a + /// reverse proxy. + /// + bool CanConnectWithHttps { get; } + /// /// Gets a value indicating whether this instance has update available. /// From e85f9f5613c009a47c9b59ac59cd5930fc45d96a Mon Sep 17 00:00:00 2001 From: Vasily Date: Tue, 7 Apr 2020 18:41:15 +0300 Subject: [PATCH 105/517] Make localhost LiveTV restreams always use plain HTTP port --- Emby.Server.Implementations/ApplicationHost.cs | 17 +++++++++-------- .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- .../TunerHosts/HdHomerun/HdHomerunUdpStream.cs | 2 +- .../LiveTv/TunerHosts/SharedHttpStream.cs | 2 +- .../IServerApplicationHost.cs | 10 +++++++--- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index cb32b8c01b..9af89112c5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1419,7 +1419,7 @@ namespace Emby.Server.Implementations public bool SupportsHttps => Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy; - public async Task GetLocalApiUrl(CancellationToken cancellationToken) + public async Task GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp=false) { try { @@ -1428,7 +1428,7 @@ namespace Emby.Server.Implementations foreach (var address in addresses) { - return GetLocalApiUrl(address); + return GetLocalApiUrl(address, forceHttp); } return null; @@ -1458,7 +1458,7 @@ namespace Emby.Server.Implementations } /// - public string GetLocalApiUrl(IPAddress ipAddress) + public string GetLocalApiUrl(IPAddress ipAddress, bool forceHttp=false) { if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { @@ -1468,20 +1468,21 @@ namespace Emby.Server.Implementations str.CopyTo(span.Slice(1)); span[^1] = ']'; - return GetLocalApiUrl(span); + return GetLocalApiUrl(span, forceHttp); } - return GetLocalApiUrl(ipAddress.ToString()); + return GetLocalApiUrl(ipAddress.ToString(), forceHttp); } /// - public string GetLocalApiUrl(ReadOnlySpan host) + public string GetLocalApiUrl(ReadOnlySpan host, bool forceHttp=false) { var url = new StringBuilder(64); - url.Append(EnableHttps ? "https://" : "http://") + bool useHttps = EnableHttps && !forceHttp; + url.Append(useHttps ? "https://" : "http://") .Append(host) .Append(':') - .Append(EnableHttps ? HttpsPort : HttpPort); + .Append(useHttps ? HttpsPort : HttpPort); string baseUrl = ServerConfigurationManager.Configuration.BaseUrl; if (baseUrl.Length != 0) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 139aa19a4b..409917245f 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1062,7 +1062,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { var stream = new MediaSourceInfo { - EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveRecordings/" + info.Id + "/stream", + EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveRecordings/" + info.Id + "/stream", EncoderProtocol = MediaProtocol.Http, Path = info.Path, Protocol = MediaProtocol.File, diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index 03ee5bfb65..d89a816b3b 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun //OpenedMediaSource.Path = tempFile; //OpenedMediaSource.ReadAtNativeFramerate = true; - MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; + MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; MediaSource.Protocol = MediaProtocol.Http; //OpenedMediaSource.SupportsDirectPlay = false; //OpenedMediaSource.SupportsDirectStream = true; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index d63588bbd1..0e600202aa 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts //OpenedMediaSource.Path = tempFile; //OpenedMediaSource.ReadAtNativeFramerate = true; - MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; + MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; MediaSource.Protocol = MediaProtocol.Http; //OpenedMediaSource.Path = TempFilePath; diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 608ffc61c2..09f6cb0431 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -65,22 +65,26 @@ namespace MediaBrowser.Controller /// /// Gets the local API URL. /// + /// Token to cancel the request if needed. + /// Whether to force usage of plain HTTP protocol. /// The local API URL. - Task GetLocalApiUrl(CancellationToken cancellationToken); + Task GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp=false); /// /// Gets the local API URL. /// /// The hostname. + /// Whether to force usage of plain HTTP protocol. /// The local API URL. - string GetLocalApiUrl(ReadOnlySpan hostname); + string GetLocalApiUrl(ReadOnlySpan hostname, bool forceHttp=false); /// /// Gets the local API URL. /// /// The IP address. + /// Whether to force usage of plain HTTP protocol. /// The local API URL. - string GetLocalApiUrl(IPAddress address); + string GetLocalApiUrl(IPAddress address, bool forceHttp=false); /// /// Open a URL in an external browser window. From 626d4dab1062050cca8b4755c79da498f4fed0b7 Mon Sep 17 00:00:00 2001 From: Vasily Date: Wed, 8 Apr 2020 13:41:11 +0300 Subject: [PATCH 106/517] Make sure Jellyfin listens on localhost no matter what This is needed by LiveTV --- Jellyfin.Server/Program.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index e55b0d4ed9..efb049a5bb 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -267,9 +267,15 @@ namespace Jellyfin.Server .LocalNetworkAddresses .Select(appHost.NormalizeConfiguredLocalAddress) .Where(i => i != null) - .ToList(); - if (addresses.Any()) + .ToHashSet(); + if (addresses.Any() && !addresses.Contains(IPAddress.Any)) { + if (!addresses.Contains(IPAddress.Loopback)) + { + // we must listen on loopback for LiveTV to function regardless of the settings + addresses.Add(IPAddress.Loopback); + } + foreach (var address in addresses) { _logger.LogInformation("Kestrel listening on {IpAddress}", address); From 9eab678487e107939e206ec66b0f573463486082 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:17:38 -0400 Subject: [PATCH 107/517] Improve Fedora spec and add metapackage --- fedora/jellyfin.spec | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/fedora/jellyfin.spec b/fedora/jellyfin.spec index c15b4ee957..4071babcdc 100644 --- a/fedora/jellyfin.spec +++ b/fedora/jellyfin.spec @@ -6,10 +6,10 @@ %global dotnet_runtime centos-x64 %endif -Name: jellyfin-server +Name: jellyfin Version: 10.6.0 Release: 1%{?dist} -Summary: The Free Software Media System Server backend and API +Summary: The Free Software Media System License: GPLv3 URL: https://jellyfin.media # Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` @@ -23,22 +23,27 @@ Source16: jellyfin-firewalld.xml %{?systemd_requires} BuildRequires: systemd -Requires(pre): shadow-utils BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel -Requires: libcurl, fontconfig, freetype, openssl, glibc libicu # Requirements not packaged in main repos # COPR @dotnet-sig/dotnet or # https://packages.microsoft.com/rhel/7/prod/ BuildRequires: dotnet-runtime-3.1, dotnet-sdk-3.1 -# RPMfusion free -Requires: ffmpeg - +Requires: %{name}-server = %{version}-%{release}, %{name}-web >= 1, %{name}-web < 2 # Disable Automatic Dependency Processing AutoReqProv: no %description Jellyfin is a free software media system that puts you in control of managing and streaming your media. +%package server +# RPMfusion free +Summary: The Free Software Media System Server backend +Requires(pre): shadow-utils +Requires: ffmpeg +Requires: libcurl, fontconfig, freetype, openssl, glibc libicu + +%description server +The Jellyfin media server backend. %prep %autosetup -n jellyfin-server-%{version} -b 0 @@ -69,7 +74,7 @@ EOF %{__install} -D -m 0755 %{SOURCE14} %{buildroot}%{_libexecdir}/jellyfin/restart.sh %{__install} -D -m 0644 %{SOURCE16} %{buildroot}%{_prefix}/lib/firewalld/services/jellyfin.xml -%files +%files server %attr(755,root,root) %{_bindir}/jellyfin %{_libdir}/jellyfin/*.json %{_libdir}/jellyfin/*.dll @@ -92,14 +97,14 @@ EOF %attr(750,jellyfin,jellyfin) %dir %{_var}/cache/jellyfin %{_datadir}/licenses/jellyfin/LICENSE -%pre +%pre server getent group jellyfin >/dev/null || groupadd -r jellyfin getent passwd jellyfin >/dev/null || \ useradd -r -g jellyfin -d %{_sharedstatedir}/jellyfin -s /sbin/nologin \ -c "Jellyfin default user" jellyfin exit 0 -%post +%post server # Move existing configuration cache and logs to their new locations and symlink them. if [ $1 -gt 1 ] ; then service_state=$(systemctl is-active jellyfin.service) @@ -127,10 +132,10 @@ if [ $1 -gt 1 ] ; then fi %systemd_post jellyfin.service -%preun +%preun server %systemd_preun jellyfin.service -%postun +%postun server %systemd_postun_with_restart jellyfin.service %changelog From c10df2fe85e06efb509a889bd7aae8ab5dc3a512 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:33:22 -0400 Subject: [PATCH 108/517] Improve dpkg handling in build.sh --- build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 86c8447933..b4792a25ed 100755 --- a/build.sh +++ b/build.sh @@ -34,7 +34,7 @@ list_platforms() { } do_build_native() { - if [[ $( dpkg --print-architecture | head -1 ) != "${PLATFORM##*.}" ]]; then + if [[ -f $( which dpkg ) && $( dpkg --print-architecture | head -1 ) != "${PLATFORM##*.}" ]]; then echo "Cross-building is not supported for native builds, use 'docker' builds on amd64 for cross-building." exit 1 fi @@ -43,7 +43,7 @@ do_build_native() { } do_build_docker() { - if ! dpkg --print-architecture | grep -q 'amd64'; then + if [[ -f $( which dpkg ) && $( dpkg --print-architecture | head -1 ) != "amd64" ]]; then echo "Docker-based builds only support amd64-based cross-building; use a 'native' build instead." exit 1 fi From 529a9ae544dfd804466d852d3c9babf1a660a1eb Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:37:00 -0400 Subject: [PATCH 109/517] Don't remove already-moved files --- bump_version | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bump_version b/bump_version index c868c541e6..46b7f86e05 100755 --- a/bump_version +++ b/bump_version @@ -67,8 +67,6 @@ echo -e "jellyfin (${new_version_deb}) unstable; urgency=medium cat ${debian_changelog_file} >> ${debian_changelog_temp} # Move into place mv ${debian_changelog_temp} ${debian_changelog_file} -# Clean up -rm -f ${debian_changelog_temp} # Write out a temporary Yum changelog with our new stuff prepended and some templated formatting fedora_spec_file="fedora/jellyfin.spec" @@ -95,7 +93,7 @@ popd # Move into place mv ${fedora_spec_temp} ${fedora_spec_file} # Clean up -rm -rf ${fedora_changelog_temp} ${fedora_spec_temp_dir} +rm -rf ${fedora_spec_temp_dir} # Stage the changed files for commit git add ${shared_version_file} ${build_file} ${debian_equivs_file} ${debian_changelog_file} ${fedora_spec_file} From b0e80b486b5a5047f78afd1f680b354daed94542 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:40:04 -0400 Subject: [PATCH 110/517] Use jellyfin.org everywhere --- Emby.Notifications/NotificationEntryPoint.cs | 2 +- debian/control | 2 +- fedora/jellyfin.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Emby.Notifications/NotificationEntryPoint.cs b/Emby.Notifications/NotificationEntryPoint.cs index befecc570b..869b7407e2 100644 --- a/Emby.Notifications/NotificationEntryPoint.cs +++ b/Emby.Notifications/NotificationEntryPoint.cs @@ -143,7 +143,7 @@ namespace Emby.Notifications var notification = new NotificationRequest { - Description = "Please see jellyfin.media for details.", + Description = "Please see jellyfin.org for details.", NotificationType = type, Name = _localization.GetLocalizedString("NewVersionIsAvailable") }; diff --git a/debian/control b/debian/control index 648e28ae81..5559700cf5 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Build-Depends: debhelper (>= 9), libfreetype6-dev, libssl-dev Standards-Version: 3.9.4 -Homepage: https://jellyfin.media/ +Homepage: https://jellyfin.org/ Vcs-Git: https://github.org/jellyfin/jellyfin.git Vcs-Browser: https://github.org/jellyfin/jellyfin diff --git a/fedora/jellyfin.spec b/fedora/jellyfin.spec index 4071babcdc..4e1045d740 100644 --- a/fedora/jellyfin.spec +++ b/fedora/jellyfin.spec @@ -11,7 +11,7 @@ Version: 10.6.0 Release: 1%{?dist} Summary: The Free Software Media System License: GPLv3 -URL: https://jellyfin.media +URL: https://jellyfin.org # Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` Source0: jellyfin-server-%{version}.tar.gz Source11: jellyfin.service From 406d087a465dd62ad376124fcb53692b1f666aef Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:46:16 -0400 Subject: [PATCH 111/517] Correct ARCH var in Ubuntu Dockerfiles --- deployment/Dockerfile.ubuntu.arm64 | 2 +- deployment/Dockerfile.ubuntu.armhf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/Dockerfile.ubuntu.arm64 b/deployment/Dockerfile.ubuntu.arm64 index e34ef7edd1..f91b91cd46 100644 --- a/deployment/Dockerfile.ubuntu.arm64 +++ b/deployment/Dockerfile.ubuntu.arm64 @@ -7,7 +7,7 @@ ARG SDK_VERSION=3.1 ENV SOURCE_DIR=/jellyfin ENV ARTIFACT_DIR=/dist ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=arm64 +ENV ARCH=amd64 ENV IS_DOCKER=YES # Prepare Debian build environment diff --git a/deployment/Dockerfile.ubuntu.armhf b/deployment/Dockerfile.ubuntu.armhf index 6f92c81ab1..85414614c0 100644 --- a/deployment/Dockerfile.ubuntu.armhf +++ b/deployment/Dockerfile.ubuntu.armhf @@ -7,7 +7,7 @@ ARG SDK_VERSION=3.1 ENV SOURCE_DIR=/jellyfin ENV ARTIFACT_DIR=/dist ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=armhf +ENV ARCH=amd64 ENV IS_DOCKER=YES # Prepare Debian build environment From ed735522cfd4ab8edfd7be2e4f6ce52856eb43cd Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:49:14 -0400 Subject: [PATCH 112/517] Revert "Remove old stuff" This reverts commit b9fdd96ece39a6ff0f4ff37ecba36d7a0f65fcba. --- deployment/old/README.md | 62 ++++++ deployment/old/centos-package-x64/Dockerfile | 39 ++++ deployment/old/centos-package-x64/clean.sh | 32 ++++ .../old/centos-package-x64/dependencies.txt | 1 + .../old/centos-package-x64/docker-build.sh | 18 ++ deployment/old/centos-package-x64/package.sh | 34 ++++ deployment/old/centos-package-x64/pkg-src | 1 + .../old/debian-package-arm64/Dockerfile.amd64 | 43 +++++ .../old/debian-package-arm64/Dockerfile.arm64 | 34 ++++ deployment/old/debian-package-arm64/clean.sh | 27 +++ .../old/debian-package-arm64/dependencies.txt | 1 + .../old/debian-package-arm64/docker-build.sh | 21 ++ .../old/debian-package-arm64/package.sh | 45 +++++ deployment/old/debian-package-arm64/pkg-src | 1 + .../old/debian-package-armhf/Dockerfile.amd64 | 42 ++++ .../old/debian-package-armhf/Dockerfile.armhf | 34 ++++ deployment/old/debian-package-armhf/clean.sh | 27 +++ .../old/debian-package-armhf/dependencies.txt | 1 + .../old/debian-package-armhf/docker-build.sh | 21 ++ .../old/debian-package-armhf/package.sh | 45 +++++ deployment/old/debian-package-armhf/pkg-src | 1 + deployment/old/debian-package-x64/Dockerfile | 34 ++++ deployment/old/debian-package-x64/clean.sh | 27 +++ .../old/debian-package-x64/dependencies.txt | 1 + .../old/debian-package-x64/docker-build.sh | 20 ++ deployment/old/debian-package-x64/package.sh | 34 ++++ .../old/debian-package-x64/pkg-src/changelog | 59 ++++++ .../old/debian-package-x64/pkg-src/compat | 1 + .../debian-package-x64/pkg-src/conf/jellyfin | 40 ++++ .../pkg-src/conf/jellyfin-sudoers | 37 ++++ .../pkg-src/conf/jellyfin.service.conf | 7 + .../pkg-src/conf/logging.json | 30 +++ .../old/debian-package-x64/pkg-src/control | 31 +++ .../old/debian-package-x64/pkg-src/copyright | 29 +++ .../old/debian-package-x64/pkg-src/gbp.conf | 6 + .../old/debian-package-x64/pkg-src/install | 6 + .../debian-package-x64/pkg-src/jellyfin.init | 61 ++++++ .../pkg-src/jellyfin.service | 14 ++ .../pkg-src/jellyfin.upstart | 20 ++ .../debian-package-x64/pkg-src/po/POTFILES.in | 1 + .../pkg-src/po/templates.pot | 57 ++++++ .../old/debian-package-x64/pkg-src/postinst | 92 +++++++++ .../old/debian-package-x64/pkg-src/postrm | 81 ++++++++ .../old/debian-package-x64/pkg-src/preinst | 78 ++++++++ .../old/debian-package-x64/pkg-src/prerm | 61 ++++++ .../old/debian-package-x64/pkg-src/rules | 66 +++++++ .../pkg-src/source.lintian-overrides | 3 + .../debian-package-x64/pkg-src/source/format | 1 + .../debian-package-x64/pkg-src/source/options | 11 ++ deployment/old/fedora-package-x64/Dockerfile | 33 ++++ deployment/old/fedora-package-x64/clean.sh | 32 ++++ .../old/fedora-package-x64/dependencies.txt | 1 + .../old/fedora-package-x64/docker-build.sh | 18 ++ deployment/old/fedora-package-x64/package.sh | 34 ++++ .../old/fedora-package-x64/pkg-src/.gitignore | 3 + .../old/fedora-package-x64/pkg-src/README.md | 43 +++++ .../pkg-src/jellyfin-firewalld.xml | 9 + .../fedora-package-x64/pkg-src/jellyfin.env | 34 ++++ .../pkg-src/jellyfin.override.conf | 7 + .../pkg-src/jellyfin.service | 15 ++ .../fedora-package-x64/pkg-src/jellyfin.spec | 181 ++++++++++++++++++ .../pkg-src/jellyfin.sudoers | 19 ++ .../old/fedora-package-x64/pkg-src/restart.sh | 36 ++++ deployment/old/linux-x64/Dockerfile | 37 ++++ deployment/old/linux-x64/clean.sh | 27 +++ deployment/old/linux-x64/dependencies.txt | 1 + deployment/old/linux-x64/docker-build.sh | 36 ++++ deployment/old/linux-x64/package.sh | 34 ++++ deployment/old/macos/Dockerfile | 37 ++++ deployment/old/macos/clean.sh | 27 +++ deployment/old/macos/dependencies.txt | 1 + deployment/old/macos/docker-build.sh | 36 ++++ deployment/old/macos/package.sh | 34 ++++ deployment/old/portable/Dockerfile | 37 ++++ deployment/old/portable/clean.sh | 27 +++ deployment/old/portable/dependencies.txt | 1 + deployment/old/portable/docker-build.sh | 36 ++++ deployment/old/portable/package.sh | 34 ++++ .../old/ubuntu-package-arm64/Dockerfile.amd64 | 59 ++++++ .../old/ubuntu-package-arm64/Dockerfile.arm64 | 40 ++++ deployment/old/ubuntu-package-arm64/clean.sh | 27 +++ .../old/ubuntu-package-arm64/dependencies.txt | 1 + .../old/ubuntu-package-arm64/docker-build.sh | 21 ++ .../old/ubuntu-package-arm64/package.sh | 45 +++++ deployment/old/ubuntu-package-arm64/pkg-src | 1 + .../old/ubuntu-package-armhf/Dockerfile.amd64 | 59 ++++++ .../old/ubuntu-package-armhf/Dockerfile.armhf | 40 ++++ deployment/old/ubuntu-package-armhf/clean.sh | 27 +++ .../old/ubuntu-package-armhf/dependencies.txt | 1 + .../old/ubuntu-package-armhf/docker-build.sh | 21 ++ .../old/ubuntu-package-armhf/package.sh | 45 +++++ deployment/old/ubuntu-package-armhf/pkg-src | 1 + deployment/old/ubuntu-package-x64/Dockerfile | 36 ++++ deployment/old/ubuntu-package-x64/clean.sh | 27 +++ .../old/ubuntu-package-x64/dependencies.txt | 1 + .../old/ubuntu-package-x64/docker-build.sh | 20 ++ deployment/old/ubuntu-package-x64/package.sh | 34 ++++ deployment/old/ubuntu-package-x64/pkg-src | 1 + .../old/unraid/docker-templates/README.md | 15 ++ .../old/unraid/docker-templates/jellyfin.xml | 57 ++++++ deployment/old/win-x64/Dockerfile | 37 ++++ deployment/old/win-x64/clean.sh | 27 +++ deployment/old/win-x64/dependencies.txt | 1 + deployment/old/win-x64/docker-build.sh | 61 ++++++ deployment/old/win-x64/package.sh | 34 ++++ deployment/old/win-x86/Dockerfile | 37 ++++ deployment/old/win-x86/clean.sh | 27 +++ deployment/old/win-x86/dependencies.txt | 1 + deployment/old/win-x86/docker-build.sh | 61 ++++++ deployment/old/win-x86/package.sh | 34 ++++ 110 files changed, 3207 insertions(+) create mode 100644 deployment/old/README.md create mode 100644 deployment/old/centos-package-x64/Dockerfile create mode 100755 deployment/old/centos-package-x64/clean.sh create mode 100644 deployment/old/centos-package-x64/dependencies.txt create mode 100755 deployment/old/centos-package-x64/docker-build.sh create mode 100755 deployment/old/centos-package-x64/package.sh create mode 120000 deployment/old/centos-package-x64/pkg-src create mode 100644 deployment/old/debian-package-arm64/Dockerfile.amd64 create mode 100644 deployment/old/debian-package-arm64/Dockerfile.arm64 create mode 100755 deployment/old/debian-package-arm64/clean.sh create mode 100644 deployment/old/debian-package-arm64/dependencies.txt create mode 100755 deployment/old/debian-package-arm64/docker-build.sh create mode 100755 deployment/old/debian-package-arm64/package.sh create mode 120000 deployment/old/debian-package-arm64/pkg-src create mode 100644 deployment/old/debian-package-armhf/Dockerfile.amd64 create mode 100644 deployment/old/debian-package-armhf/Dockerfile.armhf create mode 100755 deployment/old/debian-package-armhf/clean.sh create mode 100644 deployment/old/debian-package-armhf/dependencies.txt create mode 100755 deployment/old/debian-package-armhf/docker-build.sh create mode 100755 deployment/old/debian-package-armhf/package.sh create mode 120000 deployment/old/debian-package-armhf/pkg-src create mode 100644 deployment/old/debian-package-x64/Dockerfile create mode 100755 deployment/old/debian-package-x64/clean.sh create mode 100644 deployment/old/debian-package-x64/dependencies.txt create mode 100755 deployment/old/debian-package-x64/docker-build.sh create mode 100755 deployment/old/debian-package-x64/package.sh create mode 100644 deployment/old/debian-package-x64/pkg-src/changelog create mode 100644 deployment/old/debian-package-x64/pkg-src/compat create mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin create mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers create mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf create mode 100644 deployment/old/debian-package-x64/pkg-src/conf/logging.json create mode 100644 deployment/old/debian-package-x64/pkg-src/control create mode 100644 deployment/old/debian-package-x64/pkg-src/copyright create mode 100644 deployment/old/debian-package-x64/pkg-src/gbp.conf create mode 100644 deployment/old/debian-package-x64/pkg-src/install create mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.init create mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.service create mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.upstart create mode 100644 deployment/old/debian-package-x64/pkg-src/po/POTFILES.in create mode 100644 deployment/old/debian-package-x64/pkg-src/po/templates.pot create mode 100644 deployment/old/debian-package-x64/pkg-src/postinst create mode 100644 deployment/old/debian-package-x64/pkg-src/postrm create mode 100644 deployment/old/debian-package-x64/pkg-src/preinst create mode 100644 deployment/old/debian-package-x64/pkg-src/prerm create mode 100755 deployment/old/debian-package-x64/pkg-src/rules create mode 100644 deployment/old/debian-package-x64/pkg-src/source.lintian-overrides create mode 100644 deployment/old/debian-package-x64/pkg-src/source/format create mode 100644 deployment/old/debian-package-x64/pkg-src/source/options create mode 100644 deployment/old/fedora-package-x64/Dockerfile create mode 100755 deployment/old/fedora-package-x64/clean.sh create mode 100644 deployment/old/fedora-package-x64/dependencies.txt create mode 100755 deployment/old/fedora-package-x64/docker-build.sh create mode 100755 deployment/old/fedora-package-x64/package.sh create mode 100644 deployment/old/fedora-package-x64/pkg-src/.gitignore create mode 100644 deployment/old/fedora-package-x64/pkg-src/README.md create mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml create mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.env create mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf create mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.service create mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.spec create mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers create mode 100755 deployment/old/fedora-package-x64/pkg-src/restart.sh create mode 100644 deployment/old/linux-x64/Dockerfile create mode 100755 deployment/old/linux-x64/clean.sh create mode 100644 deployment/old/linux-x64/dependencies.txt create mode 100755 deployment/old/linux-x64/docker-build.sh create mode 100755 deployment/old/linux-x64/package.sh create mode 100644 deployment/old/macos/Dockerfile create mode 100755 deployment/old/macos/clean.sh create mode 100644 deployment/old/macos/dependencies.txt create mode 100755 deployment/old/macos/docker-build.sh create mode 100755 deployment/old/macos/package.sh create mode 100644 deployment/old/portable/Dockerfile create mode 100755 deployment/old/portable/clean.sh create mode 100644 deployment/old/portable/dependencies.txt create mode 100755 deployment/old/portable/docker-build.sh create mode 100755 deployment/old/portable/package.sh create mode 100644 deployment/old/ubuntu-package-arm64/Dockerfile.amd64 create mode 100644 deployment/old/ubuntu-package-arm64/Dockerfile.arm64 create mode 100755 deployment/old/ubuntu-package-arm64/clean.sh create mode 100644 deployment/old/ubuntu-package-arm64/dependencies.txt create mode 100755 deployment/old/ubuntu-package-arm64/docker-build.sh create mode 100755 deployment/old/ubuntu-package-arm64/package.sh create mode 120000 deployment/old/ubuntu-package-arm64/pkg-src create mode 100644 deployment/old/ubuntu-package-armhf/Dockerfile.amd64 create mode 100644 deployment/old/ubuntu-package-armhf/Dockerfile.armhf create mode 100755 deployment/old/ubuntu-package-armhf/clean.sh create mode 100644 deployment/old/ubuntu-package-armhf/dependencies.txt create mode 100755 deployment/old/ubuntu-package-armhf/docker-build.sh create mode 100755 deployment/old/ubuntu-package-armhf/package.sh create mode 120000 deployment/old/ubuntu-package-armhf/pkg-src create mode 100644 deployment/old/ubuntu-package-x64/Dockerfile create mode 100755 deployment/old/ubuntu-package-x64/clean.sh create mode 100644 deployment/old/ubuntu-package-x64/dependencies.txt create mode 100755 deployment/old/ubuntu-package-x64/docker-build.sh create mode 100755 deployment/old/ubuntu-package-x64/package.sh create mode 120000 deployment/old/ubuntu-package-x64/pkg-src create mode 100644 deployment/old/unraid/docker-templates/README.md create mode 100644 deployment/old/unraid/docker-templates/jellyfin.xml create mode 100644 deployment/old/win-x64/Dockerfile create mode 100755 deployment/old/win-x64/clean.sh create mode 100644 deployment/old/win-x64/dependencies.txt create mode 100755 deployment/old/win-x64/docker-build.sh create mode 100755 deployment/old/win-x64/package.sh create mode 100644 deployment/old/win-x86/Dockerfile create mode 100755 deployment/old/win-x86/clean.sh create mode 100644 deployment/old/win-x86/dependencies.txt create mode 100755 deployment/old/win-x86/docker-build.sh create mode 100755 deployment/old/win-x86/package.sh diff --git a/deployment/old/README.md b/deployment/old/README.md new file mode 100644 index 0000000000..a805f59ca3 --- /dev/null +++ b/deployment/old/README.md @@ -0,0 +1,62 @@ +# Jellyfin Packaging + +This directory contains the packaging configuration of Jellyfin for multiple platforms. The specification is below; all package platforms must follow the specification to be compatable with the central `build` script. + +## Package List + +### Operating System Packages + +* `debian-package-x64`: Package for Debian and Ubuntu amd64 systems. +* `fedora-package-x64`: Package for Fedora, CentOS, and Red Hat Enterprise Linux amd64 systems. + +### Portable Builds (archives) + +* `linux-x64`: Portable binary archive for generic Linux amd64 systems. +* `macos`: Portable binary archive for MacOS amd64 systems. +* `win-x64`: Portable binary archive for Windows amd64 systems. +* `win-x86`: Portable binary archive for Windows i386 systems. + +### Other Builds + +These builds are not necessarily run from the `build` script, but are present for other platforms. + +* `portable`: Compiled `.dll` for use with .NET Core runtime on any system. +* `docker`: Docker manifests for auto-publishing. +* `unraid`: unRaid Docker template; not built by `build` but imported into unRaid directly. +* `windows`: Support files and scripts for Windows CI build. + +## Package Specification + +### Dependencies + +* If a platform requires additional build dependencies, the required binary names, i.e. to validate `which `, should be specified in a `dependencies.txt` file inside the platform directory. + +* Each dependency should be present on its own line. + +### Action Scripts + +* Actions are defined in BASH scripts with the name `.sh` within the platform directory. + +* The list of valid actions are: + + 1. `build`: Builds a set of binaries. + 2. `package`: Assembles the compiled binaries into a package. + 3. `sign`: Performs signing actions on a package. + 4. `publish`: Performs a publishing action for a package. + 5. `clean`: Cleans up any artifacts from the previous actions. + +* All package actions are optional, however at least one should generate output files, and any that do should contain a `clean` action. + +* Actions are executed in the order specified above, and later actions may depend on former actions. + +* Actions except for `clean` should `set -o errexit` to terminate on failed actions. + +* The `clean` action should always `exit 0` even if no work is done or it fails. + +* The `clean` action can be passed a variable as argument 1, named `keep_artifacts`, containing either the value `y` or `n`. It is indended to handle situations when the user runs `build --keep-artifacts` and should be handled intelligently. Usually, this is used to preserve Docker images while still removing temporary directories. + +### Output Files + +* Upon completion of the defined actions, at least one output file must be created in the `/pkg-dist` directory. + +* Output files will be moved to the directory `jellyfin-build/` one directory above the repository root upon completion. diff --git a/deployment/old/centos-package-x64/Dockerfile b/deployment/old/centos-package-x64/Dockerfile new file mode 100644 index 0000000000..08219a2e4a --- /dev/null +++ b/deployment/old/centos-package-x64/Dockerfile @@ -0,0 +1,39 @@ +FROM centos:7 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/centos-package-x64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist + +# Prepare CentOS environment +RUN yum update -y \ + && yum install -y epel-release + +# Install build dependencies +RUN yum install -y @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git + +# Install recent NodeJS and Yarn +RUN curl -fSsLo /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo \ + && rpm -i https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm \ + && yum install -y yarn + +# Install DotNET SDK +RUN rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm \ + && rpmdev-setuptree \ + && yum install -y dotnet-sdk-${SDK_VERSION} + +# Create symlinks and directories +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ + && mkdir -p ${SOURCE_DIR}/SPECS \ + && ln -s ${PLATFORM_DIR}/pkg-src/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ + && mkdir -p ${SOURCE_DIR}/SOURCES \ + && ln -s ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/SOURCES + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/centos-package-x64/clean.sh b/deployment/old/centos-package-x64/clean.sh new file mode 100755 index 0000000000..31455de0d4 --- /dev/null +++ b/deployment/old/centos-package-x64/clean.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" +VERSION="$( grep -A1 '^Version:' ${WORKDIR}/pkg-src/jellyfin.spec | awk '{ print $NF }' )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +package_source_dir="${WORKDIR}/pkg-src" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-centos-build" + +rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null \ + || sudo rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/centos-package-x64/dependencies.txt b/deployment/old/centos-package-x64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/centos-package-x64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/centos-package-x64/docker-build.sh b/deployment/old/centos-package-x64/docker-build.sh new file mode 100755 index 0000000000..62dd144e50 --- /dev/null +++ b/deployment/old/centos-package-x64/docker-build.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Builds the RPM inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Build RPM +make -f .copr/Makefile srpm outdir=/root/rpmbuild/SRPMS +rpmbuild --rebuild -bb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/rpm +mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/centos-package-x64/package.sh b/deployment/old/centos-package-x64/package.sh new file mode 100755 index 0000000000..1b983f49d9 --- /dev/null +++ b/deployment/old/centos-package-x64/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-centos-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the RPMs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the RPMs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/rpm/* "${output_dir}" diff --git a/deployment/old/centos-package-x64/pkg-src b/deployment/old/centos-package-x64/pkg-src new file mode 120000 index 0000000000..3ff4d3cbf5 --- /dev/null +++ b/deployment/old/centos-package-x64/pkg-src @@ -0,0 +1 @@ +../fedora-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/debian-package-arm64/Dockerfile.amd64 b/deployment/old/debian-package-arm64/Dockerfile.amd64 new file mode 100644 index 0000000000..b63e08b7dd --- /dev/null +++ b/deployment/old/debian-package-arm64/Dockerfile.amd64 @@ -0,0 +1,43 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-arm64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Prepare the cross-toolchain +RUN dpkg --add-architecture arm64 \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="arm64" cross-gcc-gensource 8 \ + && cd cross-gcc-packages-amd64/cross-gcc-8-arm64 \ + && apt-get install -y gcc-8-source libstdc++-8-dev-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 libssl-dev:arm64 liblttng-ust0:arm64 libstdc++-8-dev:arm64 + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] +#ENTRYPOINT ["/bin/bash"] diff --git a/deployment/old/debian-package-arm64/Dockerfile.arm64 b/deployment/old/debian-package-arm64/Dockerfile.arm64 new file mode 100644 index 0000000000..9ca4868441 --- /dev/null +++ b/deployment/old/debian-package-arm64/Dockerfile.arm64 @@ -0,0 +1,34 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-arm64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=arm64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/5a4c8f96-1c73-401c-a6de-8e100403188a/0ce6ab39747e2508366d498f9c0a0669/dotnet-sdk-3.1.100-linux-arm64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-arm64/clean.sh b/deployment/old/debian-package-arm64/clean.sh new file mode 100755 index 0000000000..e7bfdf8b4b --- /dev/null +++ b/deployment/old/debian-package-arm64/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-debian_arm64-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/debian-package-arm64/dependencies.txt b/deployment/old/debian-package-arm64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/debian-package-arm64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/debian-package-arm64/docker-build.sh b/deployment/old/debian-package-arm64/docker-build.sh new file mode 100755 index 0000000000..67ab6bd74b --- /dev/null +++ b/deployment/old/debian-package-arm64/docker-build.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Builds the DEB inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image +sed -i '/dotnet-sdk-3.1,/d' debian/control + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -aarm64 + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/deb +mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-arm64/package.sh b/deployment/old/debian-package-arm64/package.sh new file mode 100755 index 0000000000..2091982187 --- /dev/null +++ b/deployment/old/debian-package-arm64/package.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +ARCH="$( arch )" +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-debian_arm64-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Determine which Dockerfile to use +case $ARCH in + 'x86_64') + DOCKERFILE="Dockerfile.amd64" + ;; + 'armv7l') + DOCKERFILE="Dockerfile.arm64" + ;; +esac + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-arm64/pkg-src b/deployment/old/debian-package-arm64/pkg-src new file mode 120000 index 0000000000..4c695fea17 --- /dev/null +++ b/deployment/old/debian-package-arm64/pkg-src @@ -0,0 +1 @@ +../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/debian-package-armhf/Dockerfile.amd64 b/deployment/old/debian-package-armhf/Dockerfile.amd64 new file mode 100644 index 0000000000..1b64b53148 --- /dev/null +++ b/deployment/old/debian-package-armhf/Dockerfile.amd64 @@ -0,0 +1,42 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-armhf +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Prepare the cross-toolchain +RUN dpkg --add-architecture armhf \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="armhf" cross-gcc-gensource 8 \ + && cd cross-gcc-packages-amd64/cross-gcc-8-armhf \ + && apt-get install -y gcc-8-source libstdc++-8-dev-armhf-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip binutils-arm-linux-gnueabihf libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf liblttng-ust0:armhf libstdc++-8-dev:armhf + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-armhf/Dockerfile.armhf b/deployment/old/debian-package-armhf/Dockerfile.armhf new file mode 100644 index 0000000000..dd398b5aa5 --- /dev/null +++ b/deployment/old/debian-package-armhf/Dockerfile.armhf @@ -0,0 +1,34 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-armhf +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=armhf + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/67766a96-eb8c-4cd2-bca4-ea63d2cc115c/7bf13840aa2ed88793b7315d5e0d74e6/dotnet-sdk-3.1.100-linux-arm.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-armhf/clean.sh b/deployment/old/debian-package-armhf/clean.sh new file mode 100755 index 0000000000..35a3d3e9ad --- /dev/null +++ b/deployment/old/debian-package-armhf/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-debian_armhf-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/debian-package-armhf/dependencies.txt b/deployment/old/debian-package-armhf/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/debian-package-armhf/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/debian-package-armhf/docker-build.sh b/deployment/old/debian-package-armhf/docker-build.sh new file mode 100755 index 0000000000..1bd7fb2911 --- /dev/null +++ b/deployment/old/debian-package-armhf/docker-build.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Builds the DEB inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image +sed -i '/dotnet-sdk-3.1,/d' debian/control + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -aarmhf + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/deb +mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-armhf/package.sh b/deployment/old/debian-package-armhf/package.sh new file mode 100755 index 0000000000..4a27dd8283 --- /dev/null +++ b/deployment/old/debian-package-armhf/package.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +ARCH="$( arch )" +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-debian_armhf-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Determine which Dockerfile to use +case $ARCH in + 'x86_64') + DOCKERFILE="Dockerfile.amd64" + ;; + 'armv7l') + DOCKERFILE="Dockerfile.armhf" + ;; +esac + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-armhf/pkg-src b/deployment/old/debian-package-armhf/pkg-src new file mode 120000 index 0000000000..0bb6d55249 --- /dev/null +++ b/deployment/old/debian-package-armhf/pkg-src @@ -0,0 +1 @@ +../debian-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/debian-package-x64/Dockerfile b/deployment/old/debian-package-x64/Dockerfile new file mode 100644 index 0000000000..e863d1edf9 --- /dev/null +++ b/deployment/old/debian-package-x64/Dockerfile @@ -0,0 +1,34 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-x64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-x64/clean.sh b/deployment/old/debian-package-x64/clean.sh new file mode 100755 index 0000000000..4e507bcb27 --- /dev/null +++ b/deployment/old/debian-package-x64/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-debian-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/debian-package-x64/dependencies.txt b/deployment/old/debian-package-x64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/debian-package-x64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/debian-package-x64/docker-build.sh b/deployment/old/debian-package-x64/docker-build.sh new file mode 100755 index 0000000000..962a522ebc --- /dev/null +++ b/deployment/old/debian-package-x64/docker-build.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Builds the DEB inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image +sed -i '/dotnet-sdk-3.1,/d' debian/control + +# Build DEB +dpkg-buildpackage -us -uc + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/deb +mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-x64/package.sh b/deployment/old/debian-package-x64/package.sh new file mode 100755 index 0000000000..5a416959ab --- /dev/null +++ b/deployment/old/debian-package-x64/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-debian-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-x64/pkg-src/changelog b/deployment/old/debian-package-x64/pkg-src/changelog new file mode 100644 index 0000000000..51c4822370 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/changelog @@ -0,0 +1,59 @@ +jellyfin (10.5.0-1) unstable; urgency=medium + + * New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 + + -- Jellyfin Packaging Team Fri, 11 Oct 2019 20:12:38 -0400 + +jellyfin (10.4.0-1) unstable; urgency=medium + + * New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 + + -- Jellyfin Packaging Team Sat, 31 Aug 2019 21:38:56 -0400 + +jellyfin (10.3.7-1) unstable; urgency=medium + + * New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 + + -- Jellyfin Packaging Team Wed, 24 Jul 2019 10:48:28 -0400 + +jellyfin (10.3.6-1) unstable; urgency=medium + + * New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 + + -- Jellyfin Packaging Team Sat, 06 Jul 2019 13:34:19 -0400 + +jellyfin (10.3.5-1) unstable; urgency=medium + + * New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 + + -- Jellyfin Packaging Team Sun, 09 Jun 2019 21:47:35 -0400 + +jellyfin (10.3.4-1) unstable; urgency=medium + + * New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 + + -- Jellyfin Packaging Team Thu, 06 Jun 2019 22:45:31 -0400 + +jellyfin (10.3.3-1) unstable; urgency=medium + + * New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 + + -- Jellyfin Packaging Team Fri, 17 May 2019 23:12:08 -0400 + +jellyfin (10.3.2-1) unstable; urgency=medium + + * New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 + + -- Jellyfin Packaging Team Tue, 30 Apr 2019 20:18:44 -0400 + +jellyfin (10.3.1-1) unstable; urgency=medium + + * New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 + + -- Jellyfin Packaging Team Sat, 20 Apr 2019 14:24:07 -0400 + +jellyfin (10.3.0-1) unstable; urgency=medium + + * New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 + + -- Jellyfin Packaging Team Fri, 19 Apr 2019 14:24:29 -0400 diff --git a/deployment/old/debian-package-x64/pkg-src/compat b/deployment/old/debian-package-x64/pkg-src/compat new file mode 100644 index 0000000000..45a4fb75db --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/compat @@ -0,0 +1 @@ +8 diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin new file mode 100644 index 0000000000..c6e595f15a --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin @@ -0,0 +1,40 @@ +# Jellyfin default configuration options +# This is a POSIX shell fragment + +# Use this file to override the default configurations; add additional +# options with JELLYFIN_ADD_OPTS. + +# Under systemd, use +# /etc/systemd/system/jellyfin.service.d/jellyfin.service.conf +# to override the user or this config file's location. + +# +# General options +# + +# Program directories +JELLYFIN_DATA_DIR="/var/lib/jellyfin" +JELLYFIN_CONFIG_DIR="/etc/jellyfin" +JELLYFIN_LOG_DIR="/var/log/jellyfin" +JELLYFIN_CACHE_DIR="/var/cache/jellyfin" + +# Restart script for in-app server control +JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh" + +# ffmpeg binary paths, overriding the system values +JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/lib/jellyfin-ffmpeg/ffmpeg" + +# [OPTIONAL] run Jellyfin as a headless service +#JELLYFIN_SERVICE_OPT="--service" + +# [OPTIONAL] run Jellyfin without the web app +#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" + +# +# SysV init/Upstart options +# + +# Application username +JELLYFIN_USER="jellyfin" +# Full application command +JELLYFIN_ARGS="$JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLFIN_NOWEBAPP_OPT" diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers new file mode 100644 index 0000000000..b481ba4ad4 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers @@ -0,0 +1,37 @@ +#Allow jellyfin group to start, stop and restart itself +Cmnd_Alias RESTARTSERVER_SYSV = /sbin/service jellyfin restart, /usr/sbin/service jellyfin restart +Cmnd_Alias STARTSERVER_SYSV = /sbin/service jellyfin start, /usr/sbin/service jellyfin start +Cmnd_Alias STOPSERVER_SYSV = /sbin/service jellyfin stop, /usr/sbin/service jellyfin stop +Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin +Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin +Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin +Cmnd_Alias RESTARTSERVER_INITD = /etc/init.d/jellyfin restart +Cmnd_Alias STARTSERVER_INITD = /etc/init.d/jellyfin start +Cmnd_Alias STOPSERVER_INITD = /etc/init.d/jellyfin stop + + +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSV +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSV +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSV +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_INITD +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_INITD +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_INITD + +Defaults!RESTARTSERVER_SYSV !requiretty +Defaults!STARTSERVER_SYSV !requiretty +Defaults!STOPSERVER_SYSV !requiretty +Defaults!RESTARTSERVER_SYSTEMD !requiretty +Defaults!STARTSERVER_SYSTEMD !requiretty +Defaults!STOPSERVER_SYSTEMD !requiretty +Defaults!RESTARTSERVER_INITD !requiretty +Defaults!STARTSERVER_INITD !requiretty +Defaults!STOPSERVER_INITD !requiretty + +#Allow the server to mount iso images +jellyfin ALL=(ALL) NOPASSWD: /bin/mount +jellyfin ALL=(ALL) NOPASSWD: /bin/umount + +Defaults:jellyfin !requiretty diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf new file mode 100644 index 0000000000..1b69dd74ef --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf @@ -0,0 +1,7 @@ +# Jellyfin systemd configuration options + +# Use this file to override the user or environment file location. + +[Service] +#User = jellyfin +#EnvironmentFile = /etc/default/jellyfin diff --git a/deployment/old/debian-package-x64/pkg-src/conf/logging.json b/deployment/old/debian-package-x64/pkg-src/conf/logging.json new file mode 100644 index 0000000000..f32b2089eb --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/conf/logging.json @@ -0,0 +1,30 @@ +{ + "Serilog": { + "MinimumLevel": "Information", + "WriteTo": [ + { + "Name": "Console", + "Args": { + "outputTemplate": "[{Timestamp:HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}" + } + }, + { + "Name": "Async", + "Args": { + "configure": [ + { + "Name": "File", + "Args": { + "path": "%JELLYFIN_LOG_DIR%//jellyfin.log", + "fileSizeLimitBytes": 10485700, + "rollOnFileSizeLimit": true, + "retainedFileCountLimit": 10, + "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] {Message}{NewLine}{Exception}" + } + } + ] + } + } + ] + } +} diff --git a/deployment/old/debian-package-x64/pkg-src/control b/deployment/old/debian-package-x64/pkg-src/control new file mode 100644 index 0000000000..13fd3ecabb --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/control @@ -0,0 +1,31 @@ +Source: jellyfin +Section: misc +Priority: optional +Maintainer: Jellyfin Team +Build-Depends: debhelper (>= 9), + dotnet-sdk-3.1, + libc6-dev, + libcurl4-openssl-dev, + libfontconfig1-dev, + libfreetype6-dev, + libssl-dev, + wget, + npm | nodejs +Standards-Version: 3.9.4 +Homepage: https://jellyfin.media/ +Vcs-Git: https://github.org/jellyfin/jellyfin.git +Vcs-Browser: https://github.org/jellyfin/jellyfin + +Package: jellyfin +Replaces: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server +Breaks: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server +Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server +Architecture: any +Depends: at, + libsqlite3-0, + jellyfin-ffmpeg, + libfontconfig1, + libfreetype6, + libssl1.1 +Description: Jellyfin is a home media server. + It is built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono. It features a REST-based api with built-in documentation to facilitate client development. We also have client libraries for our api to enable rapid development. diff --git a/deployment/old/debian-package-x64/pkg-src/copyright b/deployment/old/debian-package-x64/pkg-src/copyright new file mode 100644 index 0000000000..0d7a2a6007 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/copyright @@ -0,0 +1,29 @@ +Format: http://dep.debian.net/deps/dep5 +Upstream-Name: jellyfin +Source: https://github.com/jellyfin/jellyfin + +Files: * +Copyright: 2018 Jellyfin Team +License: GPL-2.0+ + +Files: debian/* +Copyright: 2018 Joshua Boniface +Copyright: 2014 Carlos Hernandez +License: GPL-2.0+ + +License: GPL-2.0+ + This package is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + . + This package is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + . + You should have received a copy of the GNU General Public License + along with this program. If not, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/deployment/old/debian-package-x64/pkg-src/gbp.conf b/deployment/old/debian-package-x64/pkg-src/gbp.conf new file mode 100644 index 0000000000..60b3d28723 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/gbp.conf @@ -0,0 +1,6 @@ +[DEFAULT] +pristine-tar = False +cleaner = fakeroot debian/rules clean + +[import-orig] +filter = [ ".git*", ".hg*", ".vs*", ".vscode*" ] diff --git a/deployment/old/debian-package-x64/pkg-src/install b/deployment/old/debian-package-x64/pkg-src/install new file mode 100644 index 0000000000..994322d141 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/install @@ -0,0 +1,6 @@ +usr/lib/jellyfin usr/lib/ +debian/conf/jellyfin etc/default/ +debian/conf/logging.json etc/jellyfin/ +debian/conf/jellyfin.service.conf etc/systemd/system/jellyfin.service.d/ +debian/conf/jellyfin-sudoers etc/sudoers.d/ +debian/bin/restart.sh usr/lib/jellyfin/ diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.init b/deployment/old/debian-package-x64/pkg-src/jellyfin.init new file mode 100644 index 0000000000..7f5642bac1 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/jellyfin.init @@ -0,0 +1,61 @@ +### BEGIN INIT INFO +# Provides: Jellyfin Media Server +# Required-Start: $local_fs $network +# Required-Stop: $local_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Jellyfin Media Server +# Description: Runs Jellyfin Server +### END INIT INFO + +set -e + +# Carry out specific functions when asked to by the system + +if test -f /etc/default/jellyfin; then + . /etc/default/jellyfin +fi + +. /lib/lsb/init-functions + +PIDFILE="/run/jellyfin.pid" + +case "$1" in + start) + log_daemon_msg "Starting Jellyfin Media Server" "jellyfin" || true + + if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then + log_end_msg 0 || true + else + log_end_msg 1 || true + fi + ;; + + stop) + log_daemon_msg "Stopping Jellyfin Media Server" "jellyfin" || true + if start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --remove-pidfile; then + log_end_msg 0 || true + else + log_end_msg 1 || true + fi + ;; + + restart) + log_daemon_msg "Restarting Jellyfin Media Server" "jellyfin" || true + start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE --remove-pidfile + if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then + log_end_msg 0 || true + else + log_end_msg 1 || true + fi + ;; + + status) + status_of_proc -p $PIDFILE /usr/bin/jellyfin jellyfin && exit 0 || exit $? + ;; + + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.service b/deployment/old/debian-package-x64/pkg-src/jellyfin.service new file mode 100644 index 0000000000..1305e238b0 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/jellyfin.service @@ -0,0 +1,14 @@ +[Unit] +Description = Jellyfin Media Server +After = network.target + +[Service] +Type = simple +EnvironmentFile = /etc/default/jellyfin +User = jellyfin +ExecStart = /usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} +Restart = on-failure +TimeoutSec = 15 + +[Install] +WantedBy = multi-user.target diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart b/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart new file mode 100644 index 0000000000..ef5bc9bcaf --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart @@ -0,0 +1,20 @@ +description "jellyfin daemon" + +start on (local-filesystems and net-device-up IFACE!=lo) +stop on runlevel [!2345] + +console log +respawn +respawn limit 10 5 + +kill timeout 20 + +script + set -x + echo "Starting $UPSTART_JOB" + + # Log file + logger -t "$0" "DEBUG: `set`" + . /etc/default/jellyfin + exec su -u $JELLYFIN_USER -c /usr/bin/jellyfin $JELLYFIN_ARGS +end script diff --git a/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in b/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in new file mode 100644 index 0000000000..cef83a3407 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in @@ -0,0 +1 @@ +[type: gettext/rfc822deb] templates diff --git a/deployment/old/debian-package-x64/pkg-src/po/templates.pot b/deployment/old/debian-package-x64/pkg-src/po/templates.pot new file mode 100644 index 0000000000..2cdcae4173 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/po/templates.pot @@ -0,0 +1,57 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: jellyfin-server\n" +"Report-Msgid-Bugs-To: jellyfin-server@packages.debian.org\n" +"POT-Creation-Date: 2015-06-12 20:51-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. Type: note +#. Description +#: ../templates:1001 +msgid "Jellyfin permission info:" +msgstr "" + +#. Type: note +#. Description +#: ../templates:1001 +msgid "" +"Jellyfin by default runs under a user named \"jellyfin\". Please ensure that the " +"user jellyfin has read and write access to any folders you wish to add to your " +"library. Otherwise please run jellyfin under a different user." +msgstr "" + +#. Type: string +#. Description +#: ../templates:2001 +msgid "Username to run Jellyfin as:" +msgstr "" + +#. Type: string +#. Description +#: ../templates:2001 +msgid "The user that jellyfin will run as." +msgstr "" + +#. Type: note +#. Description +#: ../templates:3001 +msgid "Jellyfin still running" +msgstr "" + +#. Type: note +#. Description +#: ../templates:3001 +msgid "Jellyfin is currently running. Please close it and try again." +msgstr "" diff --git a/deployment/old/debian-package-x64/pkg-src/postinst b/deployment/old/debian-package-x64/pkg-src/postinst new file mode 100644 index 0000000000..860222e051 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/postinst @@ -0,0 +1,92 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +case "$1" in + configure) + # create jellyfin group if it does not exist + if [[ -z "$(getent group jellyfin)" ]]; then + addgroup --quiet --system jellyfin > /dev/null 2>&1 + fi + # create jellyfin user if it does not exist + if [[ -z "$(getent passwd jellyfin)" ]]; then + adduser --system --ingroup jellyfin --shell /bin/false jellyfin --no-create-home --home ${PROGRAMDATA} \ + --gecos "Jellyfin default user" > /dev/null 2>&1 + fi + # ensure $PROGRAMDATA exists + if [[ ! -d $PROGRAMDATA ]]; then + mkdir $PROGRAMDATA + fi + # ensure $CONFIGDATA exists + if [[ ! -d $CONFIGDATA ]]; then + mkdir $CONFIGDATA + fi + # ensure $LOGDATA exists + if [[ ! -d $LOGDATA ]]; then + mkdir $LOGDATA + fi + # ensure $CACHEDATA exists + if [[ ! -d $CACHEDATA ]]; then + mkdir $CACHEDATA + fi + # Ensure permissions are correct on all config directories + chown -R jellyfin $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA + chgrp adm $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA + chmod 0750 $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA + + chmod +x /usr/lib/jellyfin/restart.sh > /dev/null 2>&1 || true + + # Install jellyfin symlink into /usr/bin + ln -sf /usr/lib/jellyfin/bin/jellyfin /usr/bin/jellyfin + + ;; + abort-upgrade|abort-remove|abort-deconfigure) + ;; + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER + +if [[ -x "/usr/bin/deb-systemd-helper" ]]; then + # Manual init script handling + deb-systemd-helper unmask jellyfin.service >/dev/null || true + # was-enabled defaults to true, so new installations run enable. + if deb-systemd-helper --quiet was-enabled jellyfin.service; then + # Enables the unit on first installation, creates new + # symlinks on upgrades if the unit file has changed. + deb-systemd-helper enable jellyfin.service >/dev/null || true + else + # Update the statefile to add new symlinks (if any), which need to be + # cleaned up on purge. Also remove old symlinks. + deb-systemd-helper update-state jellyfin.service >/dev/null || true + fi +fi + +# End automatically added section +# Automatically added by dh_installinit +if [[ "$1" == "configure" ]] || [[ "$1" == "abort-upgrade" ]]; then + if [[ -d "/run/systemd/systemd" ]]; then + systemctl --system daemon-reload >/dev/null || true + deb-systemd-invoke start jellyfin >/dev/null || true + elif [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.conf" ]]; then + update-rc.d jellyfin defaults >/dev/null + invoke-rc.d jellyfin start || exit $? + fi +fi +exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/postrm b/deployment/old/debian-package-x64/pkg-src/postrm new file mode 100644 index 0000000000..1d00a984ec --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/postrm @@ -0,0 +1,81 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [[ -d /run/systemd/system ]] ; then + systemctl --system daemon-reload >/dev/null || true +fi + +case "$1" in + purge) + echo PURGE | debconf-communicate $NAME > /dev/null 2>&1 || true + + if [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.connf" ]]; then + update-rc.d jellyfin remove >/dev/null 2>&1 || true + fi + + if [[ -x "/usr/bin/deb-systemd-helper" ]]; then + deb-systemd-helper purge jellyfin.service >/dev/null + deb-systemd-helper unmask jellyfin.service >/dev/null + fi + + # Remove user and group + userdel jellyfin > /dev/null 2>&1 || true + delgroup --quiet jellyfin > /dev/null 2>&1 || true + # Remove config dir + if [[ -d $CONFIGDATA ]]; then + rm -rf $CONFIGDATA + fi + # Remove log dir + if [[ -d $LOGDATA ]]; then + rm -rf $LOGDATA + fi + # Remove cache dir + if [[ -d $CACHEDATA ]]; then + rm -rf $CACHEDATA + fi + # Remove program data dir + if [[ -d $PROGRAMDATA ]]; then + rm -rf $PROGRAMDATA + fi + # Remove binary symlink + [[ -f /usr/bin/jellyfin ]] && rm /usr/bin/jellyfin + # Remove sudoers config + [[ -f /etc/sudoers.d/jellyfin-sudoers ]] && rm /etc/sudoers.d/jellyfin-sudoers + # Remove anything at the default locations; catches situations where the user moved the defaults + [[ -e /etc/jellyfin ]] && rm -rf /etc/jellyfin + [[ -e /var/log/jellyfin ]] && rm -rf /var/log/jellyfin + [[ -e /var/cache/jellyfin ]] && rm -rf /var/cache/jellyfin + [[ -e /var/lib/jellyfin ]] && rm -rf /var/lib/jellyfin + ;; + remove) + if [[ -x "/usr/bin/deb-systemd-helper" ]]; then + deb-systemd-helper mask jellyfin.service >/dev/null + fi + ;; + upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/preinst b/deployment/old/debian-package-x64/pkg-src/preinst new file mode 100644 index 0000000000..2713fb9b80 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/preinst @@ -0,0 +1,78 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +# In case this system is running systemd, we make systemd reload the unit files +# to pick up changes. +if [[ -d /run/systemd/system ]] ; then + systemctl --system daemon-reload >/dev/null || true +fi + +case "$1" in + install|upgrade) + # try graceful termination; + if [[ -d /run/systemd/system ]]; then + deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true + elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then + invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true + fi + # try and figure out if jellyfin is running + PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) + [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) + # if its running, let's stop it + if [[ -n "$JELLYFIN_PID" ]]; then + echo "Stopping Jellyfin!" + # if jellyfin is still running, kill it + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + CPIDS=$(pgrep -P $JELLYFIN_PID) + sleep 2 && kill -KILL $CPIDS + kill -TERM $CPIDS > /dev/null 2>&1 + fi + sleep 1 + # if it's still running, show error + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + echo "Could not successfully stop JellyfinServer, please do so before uninstalling." + exit 1 + else + [[ -f $PIDFILE ]] && rm $PIDFILE + fi + fi + + # Clean up old Emby cruft that can break the user's system + [[ -f /etc/sudoers.d/emby ]] && rm -f /etc/sudoers.d/emby + + # If we have existing config, log, or cache dirs in /var/lib/jellyfin, move them into the right place + if [[ -d $PROGRAMDATA/config ]]; then + mv $PROGRAMDATA/config $CONFIGDATA + fi + if [[ -d $PROGRAMDATA/logs ]]; then + mv $PROGRAMDATA/logs $LOGDATA + fi + if [[ -d $PROGRAMDATA/logs ]]; then + mv $PROGRAMDATA/cache $CACHEDATA + fi + + ;; + abort-upgrade) + ;; + *) + echo "preinst called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac +#DEBHELPER# + +exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/prerm b/deployment/old/debian-package-x64/pkg-src/prerm new file mode 100644 index 0000000000..e965cb7d71 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/prerm @@ -0,0 +1,61 @@ +#!/bin/bash +set -e + +NAME=jellyfin +DEFAULT_FILE=/etc/default/${NAME} + +# Source Jellyfin default configuration +if [[ -f $DEFAULT_FILE ]]; then + . $DEFAULT_FILE +fi + +# Data directories for program data (cache, db), configs, and logs +PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} +CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} +LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} +CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} + +case "$1" in + remove|upgrade|deconfigure) + echo "Stopping Jellyfin!" + # try graceful termination; + if [[ -d /run/systemd/system ]]; then + deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true + elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then + invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true + fi + # Ensure that it is shutdown + PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) + [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) + # if its running, let's stop it + if [[ -n "$JELLYFIN_PID" ]]; then + # if jellyfin is still running, kill it + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + CPIDS=$(pgrep -P $JELLYFIN_PID) + sleep 2 && kill -KILL $CPIDS + kill -TERM $CPIDS > /dev/null 2>&1 + fi + sleep 1 + # if it's still running, show error + if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then + echo "Could not successfully stop Jellyfin, please do so before uninstalling." + exit 1 + else + [[ -f $PIDFILE ]] && rm $PIDFILE + fi + fi + if [[ -f /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so ]]; then + rm /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so + fi + ;; + failed-upgrade) + ;; + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +#DEBHELPER# + +exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/rules b/deployment/old/debian-package-x64/pkg-src/rules new file mode 100755 index 0000000000..c2d57dfb22 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/rules @@ -0,0 +1,66 @@ +#! /usr/bin/make -f +CONFIG := Release +TERM := xterm +SHELL := /bin/bash +WEB_TARGET := $(CURDIR)/MediaBrowser.WebDashboard/jellyfin-web +WEB_VERSION := $(shell sed -n -e 's/^version: "\(.*\)"/\1/p' $(CURDIR)/build.yaml) + +HOST_ARCH := $(shell arch) +BUILD_ARCH := ${DEB_HOST_MULTIARCH} +ifeq ($(HOST_ARCH),x86_64) + # Building AMD64 + DOTNETRUNTIME := debian-x64 + ifeq ($(BUILD_ARCH),arm-linux-gnueabihf) + # Cross-building ARM on AMD64 + DOTNETRUNTIME := debian-arm + endif + ifeq ($(BUILD_ARCH),aarch64-linux-gnu) + # Cross-building ARM on AMD64 + DOTNETRUNTIME := debian-arm64 + endif +endif +ifeq ($(HOST_ARCH),armv7l) + # Building ARM + DOTNETRUNTIME := debian-arm +endif +ifeq ($(HOST_ARCH),arm64) + # Building ARM + DOTNETRUNTIME := debian-arm64 +endif + +export DH_VERBOSE=1 +export DOTNET_CLI_TELEMETRY_OPTOUT=1 + +%: + dh $@ + +# disable "make check" +override_dh_auto_test: + +# disable stripping debugging symbols +override_dh_clistrip: + +override_dh_auto_build: + echo $(WEB_VERSION) + # Clone down and build Web frontend + mkdir -p $(WEB_TARGET) + wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/v$(WEB_VERSION).tar.gz || wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/master.tar.gz + mkdir -p $(CURDIR)/web + tar -xzf web-src.tgz -C $(CURDIR)/web/ --strip 1 + cd $(CURDIR)/web/ && npm install yarn + cd $(CURDIR)/web/ && node_modules/yarn/bin/yarn install + mv $(CURDIR)/web/dist/* $(WEB_TARGET)/ + # Build the application + dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) \ + "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server + +override_dh_auto_clean: + dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true + rm -f '$(CURDIR)/web-src.tgz' + rm -rf '$(CURDIR)/usr' + rm -rf '$(CURDIR)/web' + rm -rf '$(WEB_TARGET)' + +# Force the service name to jellyfin even if we're building jellyfin-nightly +override_dh_installinit: + dh_installinit --name=jellyfin diff --git a/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides b/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides new file mode 100644 index 0000000000..aeb332f13a --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides @@ -0,0 +1,3 @@ +# This is an override for the following lintian errors: +jellyfin source: license-problem-md5sum-non-free-file Emby.Drawing/ImageMagick/fonts/webdings.ttf* +jellyfin source: source-is-missing diff --git a/deployment/old/debian-package-x64/pkg-src/source/format b/deployment/old/debian-package-x64/pkg-src/source/format new file mode 100644 index 0000000000..d3827e75a5 --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/source/format @@ -0,0 +1 @@ +1.0 diff --git a/deployment/old/debian-package-x64/pkg-src/source/options b/deployment/old/debian-package-x64/pkg-src/source/options new file mode 100644 index 0000000000..17b5373d5e --- /dev/null +++ b/deployment/old/debian-package-x64/pkg-src/source/options @@ -0,0 +1,11 @@ +tar-ignore='.git*' +tar-ignore='**/.git' +tar-ignore='**/.hg' +tar-ignore='**/.vs' +tar-ignore='**/.vscode' +tar-ignore='deployment' +tar-ignore='**/bin' +tar-ignore='**/obj' +tar-ignore='**/.nuget' +tar-ignore='*.deb' +tar-ignore='ThirdParty' diff --git a/deployment/old/fedora-package-x64/Dockerfile b/deployment/old/fedora-package-x64/Dockerfile new file mode 100644 index 0000000000..87120f3a05 --- /dev/null +++ b/deployment/old/fedora-package-x64/Dockerfile @@ -0,0 +1,33 @@ +FROM fedora:31 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/fedora-package-x64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist + +# Prepare Fedora environment +RUN dnf update -y + +# Install build dependencies +RUN dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel nodejs-yarn + +# Install DotNET SDK +RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc \ + && curl -o /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/$(rpm -E %fedora)/prod.repo \ + && dnf install -y dotnet-sdk-${SDK_VERSION} dotnet-runtime-${SDK_VERSION} + +# Create symlinks and directories +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ + && mkdir -p ${SOURCE_DIR}/SPECS \ + && ln -s ${PLATFORM_DIR}/pkg-src/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ + && mkdir -p ${SOURCE_DIR}/SOURCES \ + && ln -s ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/SOURCES + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/fedora-package-x64/clean.sh b/deployment/old/fedora-package-x64/clean.sh new file mode 100755 index 0000000000..700c8f1bb3 --- /dev/null +++ b/deployment/old/fedora-package-x64/clean.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" +VERSION="$( grep -A1 '^Version:' ${WORKDIR}/pkg-src/jellyfin.spec | awk '{ print $NF }' )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +package_source_dir="${WORKDIR}/pkg-src" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-fedora-build" + +rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null \ + || sudo rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/fedora-package-x64/dependencies.txt b/deployment/old/fedora-package-x64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/fedora-package-x64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/fedora-package-x64/docker-build.sh b/deployment/old/fedora-package-x64/docker-build.sh new file mode 100755 index 0000000000..740e8d35ca --- /dev/null +++ b/deployment/old/fedora-package-x64/docker-build.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Builds the RPM inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Build RPM +make -f .copr/Makefile srpm outdir=/root/rpmbuild/SRPMS +rpmbuild -rb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/rpm +mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/fedora-package-x64/package.sh b/deployment/old/fedora-package-x64/package.sh new file mode 100755 index 0000000000..ae6962dd1f --- /dev/null +++ b/deployment/old/fedora-package-x64/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-fedora-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the RPMs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the RPMs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/rpm/* "${output_dir}" diff --git a/deployment/old/fedora-package-x64/pkg-src/.gitignore b/deployment/old/fedora-package-x64/pkg-src/.gitignore new file mode 100644 index 0000000000..6019b98c22 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/.gitignore @@ -0,0 +1,3 @@ +*.rpm +*.zip +*.tar.gz \ No newline at end of file diff --git a/deployment/old/fedora-package-x64/pkg-src/README.md b/deployment/old/fedora-package-x64/pkg-src/README.md new file mode 100644 index 0000000000..7ed6f7efc6 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/README.md @@ -0,0 +1,43 @@ +# Jellyfin RPM + +## Build Fedora Package with docker + +Change into this directory `cd rpm-package` +Run the build script `./build-fedora-rpm.sh`. +Resulting RPM and src.rpm will be in `../../jellyfin-*.rpm` + +## ffmpeg + +The RPM package for Fedora/CentOS requires some additional repositories as ffmpeg is not in the main repositories. + +```shell +# ffmpeg from RPMfusion free +# Fedora +$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm +# CentOS 7 +$ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm +``` + +## ISO mounting + +To allow Jellyfin to mount/umount ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` +``` +# %jellyfin ALL=(ALL) NOPASSWD: /bin/mount +# %jellyfin ALL=(ALL) NOPASSWD: /bin/umount +``` + +## Building with dotnet + +Jellyfin is build with `--self-contained` so no dotnet required for runtime. + +```shell +# dotnet required for building the RPM +# Fedora +$ sudo dnf copr enable @dotnet-sig/dotnet +# CentOS +$ sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm +``` + +## TODO + +- [ ] OpenSUSE \ No newline at end of file diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml b/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml new file mode 100644 index 0000000000..538c5d65f8 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml @@ -0,0 +1,9 @@ + + + Jellyfin + The Free Software Media System. + + + + + diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.env b/deployment/old/fedora-package-x64/pkg-src/jellyfin.env new file mode 100644 index 0000000000..de48f13af5 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/jellyfin.env @@ -0,0 +1,34 @@ +# Jellyfin default configuration options + +# Use this file to override the default configurations; add additional +# options with JELLYFIN_ADD_OPTS. + +# To override the user or this config file's location, use +# /etc/systemd/system/jellyfin.service.d/override.conf + +# +# This is a POSIX shell fragment +# + +# +# General options +# + +# Program directories +JELLYFIN_DATA_DIR="/var/lib/jellyfin" +JELLYFIN_CONFIG_DIR="/etc/jellyfin" +JELLYFIN_LOG_DIR="/var/log/jellyfin" +JELLYFIN_CACHE_DIR="/var/cache/jellyfin" + +# In-App service control +JELLYFIN_RESTART_OPT="--restartpath=/usr/libexec/jellyfin/restart.sh" + +# [OPTIONAL] ffmpeg binary paths, overriding the UI-configured values +#JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/bin/ffmpeg" + +# [OPTIONAL] run Jellyfin as a headless service +#JELLYFIN_SERVICE_OPT="--service" + +# [OPTIONAL] run Jellyfin without the web app +#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" + diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf b/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf new file mode 100644 index 0000000000..8652450bb4 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf @@ -0,0 +1,7 @@ +# Jellyfin systemd configuration options + +# Use this file to override the user or environment file location. + +[Service] +#User = jellyfin +#EnvironmentFile = /etc/sysconfig/jellyfin diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.service b/deployment/old/fedora-package-x64/pkg-src/jellyfin.service new file mode 100644 index 0000000000..f3dc594b1c --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/jellyfin.service @@ -0,0 +1,15 @@ +[Unit] +After=network.target +Description=Jellyfin is a free software media system that puts you in control of managing and streaming your media. + +[Service] +EnvironmentFile=/etc/sysconfig/jellyfin +WorkingDirectory=/var/lib/jellyfin +ExecStart=/usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} +TimeoutSec=15 +Restart=on-failure +User=jellyfin +Group=jellyfin + +[Install] +WantedBy=multi-user.target diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec new file mode 100644 index 0000000000..33c6f6f648 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec @@ -0,0 +1,181 @@ +%global debug_package %{nil} +# Set the dotnet runtime +%if 0%{?fedora} +%global dotnet_runtime fedora-x64 +%else +%global dotnet_runtime centos-x64 +%endif + +Name: jellyfin +Version: 10.5.0 +Release: 1%{?dist} +Summary: The Free Software Media Browser +License: GPLv2 +URL: https://jellyfin.media +# Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` +Source0: https://github.com/%{name}/%{name}/archive/%{name}-%{version}.tar.gz +# Jellyfin Webinterface downloaded by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` +Source1: https://github.com/%{name}/%{name}-web/archive/%{name}-web-%{version}.tar.gz +Source11: jellyfin.service +Source12: jellyfin.env +Source13: jellyfin.sudoers +Source14: restart.sh +Source15: jellyfin.override.conf +Source16: jellyfin-firewalld.xml + +%{?systemd_requires} +BuildRequires: systemd +Requires(pre): shadow-utils +BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel, git +%if 0%{?fedora} +BuildRequires: nodejs-yarn, git +%else +# Requirements not packaged in main repos +# From https://rpm.nodesource.com/pub_10.x/el/7/x86_64/ +BuildRequires: nodejs >= 10 yarn +%endif +Requires: libcurl, fontconfig, freetype, openssl, glibc libicu +# Requirements not packaged in main repos +# COPR @dotnet-sig/dotnet or +# https://packages.microsoft.com/rhel/7/prod/ +BuildRequires: dotnet-runtime-3.1, dotnet-sdk-3.1 +# RPMfusion free +Requires: ffmpeg + +# Disable Automatic Dependency Processing +AutoReqProv: no + +%description +Jellyfin is a free software media system that puts you in control of managing and streaming your media. + + +%prep +%autosetup -n %{name}-%{version} -b 0 -b 1 +web_build_dir="$(mktemp -d)" +web_target="$PWD/MediaBrowser.WebDashboard/jellyfin-web" +pushd ../jellyfin-web-%{version} || pushd ../jellyfin-web-master +%if 0%{?fedora} +nodejs-yarn install +%else +yarn install +%endif +mkdir -p ${web_target} +mv dist/* ${web_target}/ +popd + +%build + +%install +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 +dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime %{dotnet_runtime} \ + "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server +%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE +%{__install} -D -m 0644 %{SOURCE15} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json +%{__mkdir} -p %{buildroot}%{_bindir} +tee %{buildroot}%{_bindir}/jellyfin << EOF +#!/bin/sh +exec %{_libdir}/%{name}/%{name} \${@} +EOF +%{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin +%{__mkdir} -p %{buildroot}%{_sysconfdir}/%{name} +%{__mkdir} -p %{buildroot}%{_var}/log/jellyfin +%{__mkdir} -p %{buildroot}%{_var}/cache/jellyfin + +%{__install} -D -m 0644 %{SOURCE11} %{buildroot}%{_unitdir}/%{name}.service +%{__install} -D -m 0644 %{SOURCE12} %{buildroot}%{_sysconfdir}/sysconfig/%{name} +%{__install} -D -m 0600 %{SOURCE13} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers +%{__install} -D -m 0755 %{SOURCE14} %{buildroot}%{_libexecdir}/%{name}/restart.sh +%{__install} -D -m 0644 %{SOURCE16} %{buildroot}%{_prefix}/lib/firewalld/services/%{name}.xml + +%files +%{_libdir}/%{name}/jellyfin-web/* +%attr(755,root,root) %{_bindir}/%{name} +%{_libdir}/%{name}/*.json +%{_libdir}/%{name}/*.dll +%{_libdir}/%{name}/*.so +%{_libdir}/%{name}/*.a +%{_libdir}/%{name}/createdump +# Needs 755 else only root can run it since binary build by dotnet is 722 +%attr(755,root,root) %{_libdir}/%{name}/jellyfin +%{_libdir}/%{name}/SOS_README.md +%{_unitdir}/%{name}.service +%{_libexecdir}/%{name}/restart.sh +%{_prefix}/lib/firewalld/services/%{name}.xml +%attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} +%config %{_sysconfdir}/sysconfig/%{name} +%config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers +%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf +%config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/%{name}/logging.json +%attr(750,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin +%attr(-,jellyfin,jellyfin) %dir %{_var}/log/jellyfin +%attr(750,jellyfin,jellyfin) %dir %{_var}/cache/jellyfin +%if 0%{?fedora} +%license LICENSE +%else +%{_datadir}/licenses/%{name}/LICENSE +%endif + +%pre +getent group jellyfin >/dev/null || groupadd -r jellyfin +getent passwd jellyfin >/dev/null || \ + useradd -r -g jellyfin -d %{_sharedstatedir}/jellyfin -s /sbin/nologin \ + -c "Jellyfin default user" jellyfin +exit 0 + +%post +# Move existing configuration cache and logs to their new locations and symlink them. +if [ $1 -gt 1 ] ; then + service_state=$(systemctl is-active jellyfin.service) + if [ "${service_state}" = "active" ]; then + systemctl stop jellyfin.service + fi + if [ ! -L %{_sharedstatedir}/%{name}/config ]; then + mv %{_sharedstatedir}/%{name}/config/* %{_sysconfdir}/%{name}/ + rmdir %{_sharedstatedir}/%{name}/config + ln -sf %{_sysconfdir}/%{name} %{_sharedstatedir}/%{name}/config + fi + if [ ! -L %{_sharedstatedir}/%{name}/logs ]; then + mv %{_sharedstatedir}/%{name}/logs/* %{_var}/log/jellyfin + rmdir %{_sharedstatedir}/%{name}/logs + ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/%{name}/logs + fi + if [ ! -L %{_sharedstatedir}/%{name}/cache ]; then + mv %{_sharedstatedir}/%{name}/cache/* %{_var}/cache/jellyfin + rmdir %{_sharedstatedir}/%{name}/cache + ln -sf %{_var}/cache/jellyfin %{_sharedstatedir}/%{name}/cache + fi + if [ "${service_state}" = "active" ]; then + systemctl start jellyfin.service + fi +fi +%systemd_post jellyfin.service + +%preun +%systemd_preun jellyfin.service + +%postun +%systemd_postun_with_restart jellyfin.service + +%changelog +* Fri Oct 11 2019 Jellyfin Packaging Team +- New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 +* Sat Aug 31 2019 Jellyfin Packaging Team +- New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 +* Wed Jul 24 2019 Jellyfin Packaging Team +- New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 +* Sat Jul 06 2019 Jellyfin Packaging Team +- New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 +* Sun Jun 09 2019 Jellyfin Packaging Team +- New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 +* Thu Jun 06 2019 Jellyfin Packaging Team +- New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 +* Fri May 17 2019 Jellyfin Packaging Team +- New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 +* Tue Apr 30 2019 Jellyfin Packaging Team +- New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 +* Sat Apr 20 2019 Jellyfin Packaging Team +- New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 +* Fri Apr 19 2019 Jellyfin Packaging Team +- New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers b/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers new file mode 100644 index 0000000000..dd245af4b8 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers @@ -0,0 +1,19 @@ +# Allow jellyfin group to start, stop and restart itself +Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin +Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin +Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin + + +jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD +jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD + +Defaults!RESTARTSERVER_SYSTEMD !requiretty +Defaults!STARTSERVER_SYSTEMD !requiretty +Defaults!STOPSERVER_SYSTEMD !requiretty + +# Allow the server to mount iso images +jellyfin ALL=(ALL) NOPASSWD: /bin/mount +jellyfin ALL=(ALL) NOPASSWD: /bin/umount + +Defaults:jellyfin !requiretty diff --git a/deployment/old/fedora-package-x64/pkg-src/restart.sh b/deployment/old/fedora-package-x64/pkg-src/restart.sh new file mode 100755 index 0000000000..9b64b6d728 --- /dev/null +++ b/deployment/old/fedora-package-x64/pkg-src/restart.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# restart.sh - Jellyfin server restart script +# Part of the Jellyfin project (https://github.com/jellyfin) +# +# This script restarts the Jellyfin daemon on Linux when using +# the Restart button on the admin dashboard. It supports the +# systemctl, service, and traditional /etc/init.d (sysv) restart +# methods, chosen automatically by which one is found first (in +# that order). +# +# This script is used by the Debian/Ubuntu/Fedora/CentOS packages. + +get_service_command() { + for command in systemctl service; do + if which $command &>/dev/null; then + echo $command && return + fi + done + echo "sysv" +} + +cmd="$( get_service_command )" +echo "Detected service control platform '$cmd'; using it to restart Jellyfin..." +case $cmd in + 'systemctl') + echo "sleep 2; /usr/bin/sudo $( which systemctl ) restart jellyfin" | at now + ;; + 'service') + echo "sleep 2; /usr/bin/sudo $( which service ) jellyfin restart" | at now + ;; + 'sysv') + echo "sleep 2; /usr/bin/sudo /etc/init.d/jellyfin restart" | at now + ;; +esac +exit 0 diff --git a/deployment/old/linux-x64/Dockerfile b/deployment/old/linux-x64/Dockerfile new file mode 100644 index 0000000000..c47057546d --- /dev/null +++ b/deployment/old/linux-x64/Dockerfile @@ -0,0 +1,37 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/linux-x64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install yarn package manager +RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && apt update \ + && apt install -y yarn + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/linux-x64/clean.sh b/deployment/old/linux-x64/clean.sh new file mode 100755 index 0000000000..c07501a7bb --- /dev/null +++ b/deployment/old/linux-x64/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-linux-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/linux-x64/dependencies.txt b/deployment/old/linux-x64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/linux-x64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/linux-x64/docker-build.sh b/deployment/old/linux-x64/docker-build.sh new file mode 100755 index 0000000000..e33328a36a --- /dev/null +++ b/deployment/old/linux-x64/docker-build.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Builds the TAR archive inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Clone down and build Web frontend +web_build_dir="$( mktemp -d )" +web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" +git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ +pushd ${web_build_dir} +if [[ -n ${web_branch} ]]; then + checkout -b origin/${web_branch} +fi +yarn install +mkdir -p ${web_target} +mv dist/* ${web_target}/ +popd +rm -rf ${web_build_dir} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build archives +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" +tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} +rm -rf /dist/jellyfin_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/linux-x64/package.sh b/deployment/old/linux-x64/package.sh new file mode 100755 index 0000000000..dfe8a9aa4a --- /dev/null +++ b/deployment/old/linux-x64/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-linux-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/macos/Dockerfile b/deployment/old/macos/Dockerfile new file mode 100644 index 0000000000..b522df8848 --- /dev/null +++ b/deployment/old/macos/Dockerfile @@ -0,0 +1,37 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/macos +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install yarn package manager +RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && apt update \ + && apt install -y yarn + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/macos/clean.sh b/deployment/old/macos/clean.sh new file mode 100755 index 0000000000..c07501a7bb --- /dev/null +++ b/deployment/old/macos/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-linux-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/macos/dependencies.txt b/deployment/old/macos/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/macos/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/macos/docker-build.sh b/deployment/old/macos/docker-build.sh new file mode 100755 index 0000000000..f9417388d7 --- /dev/null +++ b/deployment/old/macos/docker-build.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Builds the TAR archive inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Clone down and build Web frontend +web_build_dir="$( mktemp -d )" +web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" +git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ +pushd ${web_build_dir} +if [[ -n ${web_branch} ]]; then + checkout -b origin/${web_branch} +fi +yarn install +mkdir -p ${web_target} +mv dist/* ${web_target}/ +popd +rm -rf ${web_build_dir} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build archives +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" +tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} +rm -rf /dist/jellyfin_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/macos/package.sh b/deployment/old/macos/package.sh new file mode 100755 index 0000000000..464c0d382f --- /dev/null +++ b/deployment/old/macos/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-macos-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/portable/Dockerfile b/deployment/old/portable/Dockerfile new file mode 100644 index 0000000000..965eb82b86 --- /dev/null +++ b/deployment/old/portable/Dockerfile @@ -0,0 +1,37 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/portable +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install yarn package manager +RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && apt update \ + && apt install -y yarn + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/portable/clean.sh b/deployment/old/portable/clean.sh new file mode 100755 index 0000000000..c07501a7bb --- /dev/null +++ b/deployment/old/portable/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-linux-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/portable/dependencies.txt b/deployment/old/portable/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/portable/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/portable/docker-build.sh b/deployment/old/portable/docker-build.sh new file mode 100755 index 0000000000..094190bbf6 --- /dev/null +++ b/deployment/old/portable/docker-build.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Builds the TAR archive inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Clone down and build Web frontend +web_build_dir="$( mktemp -d )" +web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" +git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ +pushd ${web_build_dir} +if [[ -n ${web_branch} ]]; then + checkout -b origin/${web_branch} +fi +yarn install +mkdir -p ${web_target} +mv dist/* ${web_target}/ +popd +rm -rf ${web_build_dir} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build archives +dotnet publish Jellyfin.Server --configuration Release --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" +tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} +rm -rf /dist/jellyfin_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/portable/package.sh b/deployment/old/portable/package.sh new file mode 100755 index 0000000000..0ceb54dda1 --- /dev/null +++ b/deployment/old/portable/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-portable-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 b/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 new file mode 100644 index 0000000000..b11994a18a --- /dev/null +++ b/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 @@ -0,0 +1,59 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-arm64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install npm package manager +RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ + && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ + && apt update \ + && apt install -y nodejs + +# Prepare the cross-toolchain +RUN rm /etc/apt/sources.list \ + && export CODENAME="$( lsb_release -c -s )" \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ + && dpkg --add-architecture arm64 \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="arm64" cross-gcc-gensource 6 \ + && cd cross-gcc-packages-amd64/cross-gcc-6-arm64 \ + && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ + && apt-get install -y gcc-6-source libstdc++6-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 liblttng-ust0:arm64 libstdc++6:arm64 libssl-dev:arm64 + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 b/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 new file mode 100644 index 0000000000..8f004b2f1a --- /dev/null +++ b/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 @@ -0,0 +1,40 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-arm64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=arm64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev liblttng-ust0 libssl-dev + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/5a4c8f96-1c73-401c-a6de-8e100403188a/0ce6ab39747e2508366d498f9c0a0669/dotnet-sdk-3.1.100-linux-arm64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install npm package manager +RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ + && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ + && apt update \ + && apt install -y nodejs + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-arm64/clean.sh b/deployment/old/ubuntu-package-arm64/clean.sh new file mode 100755 index 0000000000..82d427f9e5 --- /dev/null +++ b/deployment/old/ubuntu-package-arm64/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-ubuntu-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/ubuntu-package-arm64/dependencies.txt b/deployment/old/ubuntu-package-arm64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/ubuntu-package-arm64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/ubuntu-package-arm64/docker-build.sh b/deployment/old/ubuntu-package-arm64/docker-build.sh new file mode 100755 index 0000000000..67ab6bd74b --- /dev/null +++ b/deployment/old/ubuntu-package-arm64/docker-build.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Builds the DEB inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image +sed -i '/dotnet-sdk-3.1,/d' debian/control + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -aarm64 + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/deb +mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-arm64/package.sh b/deployment/old/ubuntu-package-arm64/package.sh new file mode 100755 index 0000000000..d1140a7274 --- /dev/null +++ b/deployment/old/ubuntu-package-arm64/package.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +ARCH="$( arch )" +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-ubuntu_arm64-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Determine which Dockerfile to use +case $ARCH in + 'x86_64') + DOCKERFILE="Dockerfile.amd64" + ;; + 'armv7l') + DOCKERFILE="Dockerfile.arm64" + ;; +esac + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-arm64/pkg-src b/deployment/old/ubuntu-package-arm64/pkg-src new file mode 120000 index 0000000000..4c695fea17 --- /dev/null +++ b/deployment/old/ubuntu-package-arm64/pkg-src @@ -0,0 +1 @@ +../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 b/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 new file mode 100644 index 0000000000..e475b14389 --- /dev/null +++ b/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 @@ -0,0 +1,59 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-armhf +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install npm package manager +RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ + && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ + && apt update \ + && apt install -y nodejs + +# Prepare the cross-toolchain +RUN rm /etc/apt/sources.list \ + && export CODENAME="$( lsb_release -c -s )" \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ + && dpkg --add-architecture armhf \ + && apt-get update \ + && apt-get install -y cross-gcc-dev \ + && TARGET_LIST="armhf" cross-gcc-gensource 6 \ + && cd cross-gcc-packages-amd64/cross-gcc-6-armhf \ + && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ + && apt-get install -y gcc-6-source libstdc++6-armhf-cross binutils-arm-linux-gnueabihf bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf liblttng-ust0:armhf libstdc++6:armhf libssl-dev:armhf + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-armhf/Dockerfile.armhf b/deployment/old/ubuntu-package-armhf/Dockerfile.armhf new file mode 100644 index 0000000000..0e71fa6938 --- /dev/null +++ b/deployment/old/ubuntu-package-armhf/Dockerfile.armhf @@ -0,0 +1,40 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-armhf +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=armhf + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev liblttng-ust0 libssl-dev + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/67766a96-eb8c-4cd2-bca4-ea63d2cc115c/7bf13840aa2ed88793b7315d5e0d74e6/dotnet-sdk-3.1.100-linux-arm.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install npm package manager +RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ + && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ + && apt update \ + && apt install -y nodejs + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +# Link to Debian source dir; mkdir needed or it fails, can't force dest +RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-armhf/clean.sh b/deployment/old/ubuntu-package-armhf/clean.sh new file mode 100755 index 0000000000..82d427f9e5 --- /dev/null +++ b/deployment/old/ubuntu-package-armhf/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-ubuntu-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/ubuntu-package-armhf/dependencies.txt b/deployment/old/ubuntu-package-armhf/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/ubuntu-package-armhf/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/ubuntu-package-armhf/docker-build.sh b/deployment/old/ubuntu-package-armhf/docker-build.sh new file mode 100755 index 0000000000..1bd7fb2911 --- /dev/null +++ b/deployment/old/ubuntu-package-armhf/docker-build.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Builds the DEB inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image +sed -i '/dotnet-sdk-3.1,/d' debian/control + +# Build DEB +export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} +dpkg-buildpackage -us -uc -aarmhf + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/deb +mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-armhf/package.sh b/deployment/old/ubuntu-package-armhf/package.sh new file mode 100755 index 0000000000..2ceb3e8165 --- /dev/null +++ b/deployment/old/ubuntu-package-armhf/package.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +ARCH="$( arch )" +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-ubuntu_armhf-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Determine which Dockerfile to use +case $ARCH in + 'x86_64') + DOCKERFILE="Dockerfile.amd64" + ;; + 'armv7l') + DOCKERFILE="Dockerfile.armhf" + ;; +esac + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-armhf/pkg-src b/deployment/old/ubuntu-package-armhf/pkg-src new file mode 120000 index 0000000000..4c695fea17 --- /dev/null +++ b/deployment/old/ubuntu-package-armhf/pkg-src @@ -0,0 +1 @@ +../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/ubuntu-package-x64/Dockerfile b/deployment/old/ubuntu-package-x64/Dockerfile new file mode 100644 index 0000000000..e2dda6392c --- /dev/null +++ b/deployment/old/ubuntu-package-x64/Dockerfile @@ -0,0 +1,36 @@ +FROM ubuntu:bionic +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-x64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Ubuntu build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 \ + && ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ + && mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install npm package manager +RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ + && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ + && apt update \ + && apt install -y nodejs + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-x64/clean.sh b/deployment/old/ubuntu-package-x64/clean.sh new file mode 100755 index 0000000000..82d427f9e5 --- /dev/null +++ b/deployment/old/ubuntu-package-x64/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-ubuntu-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/ubuntu-package-x64/dependencies.txt b/deployment/old/ubuntu-package-x64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/ubuntu-package-x64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/ubuntu-package-x64/docker-build.sh b/deployment/old/ubuntu-package-x64/docker-build.sh new file mode 100755 index 0000000000..962a522ebc --- /dev/null +++ b/deployment/old/ubuntu-package-x64/docker-build.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Builds the DEB inside the Docker container + +set -o errexit +set -o xtrace + +# Move to source directory +pushd ${SOURCE_DIR} + +# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image +sed -i '/dotnet-sdk-3.1,/d' debian/control + +# Build DEB +dpkg-buildpackage -us -uc + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/deb +mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-x64/package.sh b/deployment/old/ubuntu-package-x64/package.sh new file mode 100755 index 0000000000..08c003778b --- /dev/null +++ b/deployment/old/ubuntu-package-x64/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-ubuntu-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-x64/pkg-src b/deployment/old/ubuntu-package-x64/pkg-src new file mode 120000 index 0000000000..0bb6d55249 --- /dev/null +++ b/deployment/old/ubuntu-package-x64/pkg-src @@ -0,0 +1 @@ +../debian-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/unraid/docker-templates/README.md b/deployment/old/unraid/docker-templates/README.md new file mode 100644 index 0000000000..2c268e8b3e --- /dev/null +++ b/deployment/old/unraid/docker-templates/README.md @@ -0,0 +1,15 @@ +# docker-templates + +### Installation: + +Open unRaid GUI (at least unRaid 6.5) + +Click on the Docker tab + +Add the following line under "Template Repositories" + +https://github.com/jellyfin/jellyfin/blob/master/deployment/unraid/docker-templates + +Click save than click on Add Container and select jellyfin. + +Adjust to your paths to your liking and off you go! diff --git a/deployment/old/unraid/docker-templates/jellyfin.xml b/deployment/old/unraid/docker-templates/jellyfin.xml new file mode 100644 index 0000000000..57b4cc5ae1 --- /dev/null +++ b/deployment/old/unraid/docker-templates/jellyfin.xml @@ -0,0 +1,57 @@ + + + https://raw.githubusercontent.com/jellyfin/jellyfin/deployment/unraid/docker-templates/jellyfin.xml + False + MediaApp:Video MediaApp:Music MediaApp:Photos MediaServer:Video MediaServer:Music MediaServer:Photos + Jellyfin + + Jellyfin is The Free Software Media Browser Converted By Community Applications Always verify this template (and values) against the dockerhub support page for the container!![br][br] + You can add as many mount points as needed for recordings, movies ,etc. [br][br] + [b][span style='color: #E80000;']Directions:[/span][/b][br] + [b]/config[/b] : This is where Jellyfin will store it's databases and configuration.[br][br] + [b]Port[/b] : This is the default port for Jellyfin. (Will add ssl port later)[br][br] + [b]Media[/b] : This is the mounting point of your media. When you access it in Jellyfin it will be /media or whatever you chose for a mount point[br][br] + [b]Cache[/b] : This is where Jellyfin will store and manage cached files like images to serve to clients. This is not where all images are stored.[br][br] + [b]Tip:[/b] You can add more volume mappings if you wish Jellyfin has access to it. + + + Jellyfin Server is a home media server built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono and will remain completely free! + + https://www.reddit.com/r/jellyfin/ + https://hub.docker.com/r/jellyfin/jellyfin/ + https://github.com/jellyfin/jellyfin/> + jellyfin/jellyfin + https://jellyfin.media/ + true + false + + host + + + 8096 + 8096 + tcp + + + + + + /mnt/user/appdata/Jellyfin + /config + rw + + + /mnt/user + /media + rw + + + /mnt/user/appdata/Jellyfin/cache/ + /cache + rw + + + http://[IP]:[PORT:8096]/ + https://raw.githubusercontent.com/binhex/docker-templates/master/binhex/images/jellyfin-icon.png + + diff --git a/deployment/old/win-x64/Dockerfile b/deployment/old/win-x64/Dockerfile new file mode 100644 index 0000000000..8a33749541 --- /dev/null +++ b/deployment/old/win-x64/Dockerfile @@ -0,0 +1,37 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/win-x64 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install yarn package manager +RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && apt update \ + && apt install -y yarn + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/win-x64/clean.sh b/deployment/old/win-x64/clean.sh new file mode 100755 index 0000000000..6c183f3371 --- /dev/null +++ b/deployment/old/win-x64/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-windows-x64-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/win-x64/dependencies.txt b/deployment/old/win-x64/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/win-x64/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/win-x64/docker-build.sh b/deployment/old/win-x64/docker-build.sh new file mode 100755 index 0000000000..79e5fb0bcd --- /dev/null +++ b/deployment/old/win-x64/docker-build.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Builds the ZIP archive inside the Docker container + +set -o errexit +set -o xtrace + +# Version variables +NSSM_VERSION="nssm-2.24-101-g897c7ad" +NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" +FFMPEG_VERSION="ffmpeg-4.2.1-win64-static" +FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win64/static/${FFMPEG_VERSION}.zip" + +# Move to source directory +pushd ${SOURCE_DIR} + +# Clone down and build Web frontend +web_build_dir="$( mktemp -d )" +web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" +git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ +pushd ${web_build_dir} +if [[ -n ${web_branch} ]]; then + checkout -b origin/${web_branch} +fi +yarn install +mkdir -p ${web_target} +mv dist/* ${web_target}/ +popd +rm -rf ${web_build_dir} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build binary +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" + +# Prepare addins +addin_build_dir="$( mktemp -d )" +wget ${NSSM_URL} -O ${addin_build_dir}/nssm.zip +wget ${FFMPEG_URL} -O ${addin_build_dir}/ffmpeg.zip +unzip ${addin_build_dir}/nssm.zip -d ${addin_build_dir} +cp ${addin_build_dir}/${NSSM_VERSION}/win64/nssm.exe /dist/jellyfin_${version}/nssm.exe +unzip ${addin_build_dir}/ffmpeg.zip -d ${addin_build_dir} +cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffmpeg.exe /dist/jellyfin_${version}/ffmpeg.exe +cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffprobe.exe /dist/jellyfin_${version}/ffprobe.exe +rm -rf ${addin_build_dir} + +# Prepare scripts +cp ${SOURCE_DIR}/deployment/windows/legacy/install-jellyfin.ps1 /dist/jellyfin_${version}/install-jellyfin.ps1 +cp ${SOURCE_DIR}/deployment/windows/legacy/install.bat /dist/jellyfin_${version}/install.bat + +# Create zip package +pushd /dist +zip -r /jellyfin_${version}.portable.zip jellyfin_${version} +popd +rm -rf /dist/jellyfin_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv /jellyfin[-_]*.zip ${ARTIFACT_DIR}/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/win-x64/package.sh b/deployment/old/win-x64/package.sh new file mode 100755 index 0000000000..a8ab190fa5 --- /dev/null +++ b/deployment/old/win-x64/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-windows-x64-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/win-x86/Dockerfile b/deployment/old/win-x86/Dockerfile new file mode 100644 index 0000000000..f8dc5be83d --- /dev/null +++ b/deployment/old/win-x86/Dockerfile @@ -0,0 +1,37 @@ +FROM debian:10 +# Docker build arguments +ARG SOURCE_DIR=/jellyfin +ARG PLATFORM_DIR=/jellyfin/deployment/win-x86 +ARG ARTIFACT_DIR=/dist +ARG SDK_VERSION=3.1 +# Docker run environment +ENV SOURCE_DIR=/jellyfin +ENV ARTIFACT_DIR=/dist +ENV DEB_BUILD_OPTIONS=noddebs +ENV ARCH=amd64 + +# Prepare Debian build environment +RUN apt-get update \ + && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip + +# Install dotnet repository +# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current +RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ + && mkdir -p dotnet-sdk \ + && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ + && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet + +# Install yarn package manager +RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ + && apt update \ + && apt install -y yarn + +# Link to docker-build script +RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh + +VOLUME ${ARTIFACT_DIR}/ + +COPY . ${SOURCE_DIR}/ + +ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/win-x86/clean.sh b/deployment/old/win-x86/clean.sh new file mode 100755 index 0000000000..8b78c5e4b6 --- /dev/null +++ b/deployment/old/win-x86/clean.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +keep_artifacts="${1}" + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-windows-x86-build" + +rm -rf "${package_temporary_dir}" &>/dev/null \ + || sudo rm -rf "${package_temporary_dir}" &>/dev/null + +rm -rf "${output_dir}" &>/dev/null \ + || sudo rm -rf "${output_dir}" &>/dev/null + +if [[ ${keep_artifacts} == 'n' ]]; then + docker_sudo="" + if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo=sudo + fi + ${docker_sudo} docker image rm ${image_name} --force +fi diff --git a/deployment/old/win-x86/dependencies.txt b/deployment/old/win-x86/dependencies.txt new file mode 100644 index 0000000000..bdb9670965 --- /dev/null +++ b/deployment/old/win-x86/dependencies.txt @@ -0,0 +1 @@ +docker diff --git a/deployment/old/win-x86/docker-build.sh b/deployment/old/win-x86/docker-build.sh new file mode 100755 index 0000000000..977dcf78fa --- /dev/null +++ b/deployment/old/win-x86/docker-build.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# Builds the ZIP archive inside the Docker container + +set -o errexit +set -o xtrace + +# Version variables +NSSM_VERSION="nssm-2.24-101-g897c7ad" +NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" +FFMPEG_VERSION="ffmpeg-4.2.1-win32-static" +FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win32/static/${FFMPEG_VERSION}.zip" + +# Move to source directory +pushd ${SOURCE_DIR} + +# Clone down and build Web frontend +web_build_dir="$( mktemp -d )" +web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" +git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ +pushd ${web_build_dir} +if [[ -n ${web_branch} ]]; then + checkout -b origin/${web_branch} +fi +yarn install +mkdir -p ${web_target} +mv dist/* ${web_target}/ +popd +rm -rf ${web_build_dir} + +# Get version +version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" + +# Build binary +dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x86 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" + +# Prepare addins +addin_build_dir="$( mktemp -d )" +wget ${NSSM_URL} -O ${addin_build_dir}/nssm.zip +wget ${FFMPEG_URL} -O ${addin_build_dir}/ffmpeg.zip +unzip ${addin_build_dir}/nssm.zip -d ${addin_build_dir} +cp ${addin_build_dir}/${NSSM_VERSION}/win64/nssm.exe /dist/jellyfin_${version}/nssm.exe +unzip ${addin_build_dir}/ffmpeg.zip -d ${addin_build_dir} +cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffmpeg.exe /dist/jellyfin_${version}/ffmpeg.exe +cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffprobe.exe /dist/jellyfin_${version}/ffprobe.exe +rm -rf ${addin_build_dir} + +# Prepare scripts +cp ${SOURCE_DIR}/deployment/windows/legacy/install-jellyfin.ps1 /dist/jellyfin_${version}/install-jellyfin.ps1 +cp ${SOURCE_DIR}/deployment/windows/legacy/install.bat /dist/jellyfin_${version}/install.bat + +# Create zip package +pushd /dist +zip -r /jellyfin_${version}.portable.zip jellyfin_${version} +popd +rm -rf /dist/jellyfin_${version} + +# Move the artifacts out +mkdir -p ${ARTIFACT_DIR}/ +mv /jellyfin[-_]*.zip ${ARTIFACT_DIR}/ +chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/win-x86/package.sh b/deployment/old/win-x86/package.sh new file mode 100755 index 0000000000..65e7e2928c --- /dev/null +++ b/deployment/old/win-x86/package.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +args="${@}" +declare -a docker_envvars +for arg in ${args}; do + docker_envvars+=("-e ${arg}") +done + +WORKDIR="$( pwd )" + +package_temporary_dir="${WORKDIR}/pkg-dist-tmp" +output_dir="${WORKDIR}/pkg-dist" +current_user="$( whoami )" +image_name="jellyfin-windows-x86-build" + +# Determine if sudo should be used for Docker +if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ + && [[ ! ${EUID:-1000} -eq 0 ]] \ + && [[ ! ${USER} == "root" ]] \ + && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then + docker_sudo="sudo" +else + docker_sudo="" +fi + +# Prepare temporary package dir +mkdir -p "${package_temporary_dir}" +# Set up the build environment Docker image +${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile +# Build the DEBs and copy out to ${package_temporary_dir} +${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} +# Move the DEBs to the output directory +mkdir -p "${output_dir}" +mv "${package_temporary_dir}"/* "${output_dir}" From 42813ef06973126151e2c91ecb7aa6836e0d472c Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:50:32 -0400 Subject: [PATCH 113/517] Preserve Unraid configuration --- deployment/unraid/docker-templates/README.md | 15 +++++ .../unraid/docker-templates/jellyfin.xml | 57 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 deployment/unraid/docker-templates/README.md create mode 100644 deployment/unraid/docker-templates/jellyfin.xml diff --git a/deployment/unraid/docker-templates/README.md b/deployment/unraid/docker-templates/README.md new file mode 100644 index 0000000000..2c268e8b3e --- /dev/null +++ b/deployment/unraid/docker-templates/README.md @@ -0,0 +1,15 @@ +# docker-templates + +### Installation: + +Open unRaid GUI (at least unRaid 6.5) + +Click on the Docker tab + +Add the following line under "Template Repositories" + +https://github.com/jellyfin/jellyfin/blob/master/deployment/unraid/docker-templates + +Click save than click on Add Container and select jellyfin. + +Adjust to your paths to your liking and off you go! diff --git a/deployment/unraid/docker-templates/jellyfin.xml b/deployment/unraid/docker-templates/jellyfin.xml new file mode 100644 index 0000000000..57b4cc5ae1 --- /dev/null +++ b/deployment/unraid/docker-templates/jellyfin.xml @@ -0,0 +1,57 @@ + + + https://raw.githubusercontent.com/jellyfin/jellyfin/deployment/unraid/docker-templates/jellyfin.xml + False + MediaApp:Video MediaApp:Music MediaApp:Photos MediaServer:Video MediaServer:Music MediaServer:Photos + Jellyfin + + Jellyfin is The Free Software Media Browser Converted By Community Applications Always verify this template (and values) against the dockerhub support page for the container!![br][br] + You can add as many mount points as needed for recordings, movies ,etc. [br][br] + [b][span style='color: #E80000;']Directions:[/span][/b][br] + [b]/config[/b] : This is where Jellyfin will store it's databases and configuration.[br][br] + [b]Port[/b] : This is the default port for Jellyfin. (Will add ssl port later)[br][br] + [b]Media[/b] : This is the mounting point of your media. When you access it in Jellyfin it will be /media or whatever you chose for a mount point[br][br] + [b]Cache[/b] : This is where Jellyfin will store and manage cached files like images to serve to clients. This is not where all images are stored.[br][br] + [b]Tip:[/b] You can add more volume mappings if you wish Jellyfin has access to it. + + + Jellyfin Server is a home media server built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono and will remain completely free! + + https://www.reddit.com/r/jellyfin/ + https://hub.docker.com/r/jellyfin/jellyfin/ + https://github.com/jellyfin/jellyfin/> + jellyfin/jellyfin + https://jellyfin.media/ + true + false + + host + + + 8096 + 8096 + tcp + + + + + + /mnt/user/appdata/Jellyfin + /config + rw + + + /mnt/user + /media + rw + + + /mnt/user/appdata/Jellyfin/cache/ + /cache + rw + + + http://[IP]:[PORT:8096]/ + https://raw.githubusercontent.com/binhex/docker-templates/master/binhex/images/jellyfin-icon.png + + From fbad4f00b4a95b889708d430ad445a58dad2f964 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:50:46 -0400 Subject: [PATCH 114/517] Remove old build infra (again) --- deployment/old/README.md | 62 ------ deployment/old/centos-package-x64/Dockerfile | 39 ---- deployment/old/centos-package-x64/clean.sh | 32 ---- .../old/centos-package-x64/dependencies.txt | 1 - .../old/centos-package-x64/docker-build.sh | 18 -- deployment/old/centos-package-x64/package.sh | 34 ---- deployment/old/centos-package-x64/pkg-src | 1 - .../old/debian-package-arm64/Dockerfile.amd64 | 43 ----- .../old/debian-package-arm64/Dockerfile.arm64 | 34 ---- deployment/old/debian-package-arm64/clean.sh | 27 --- .../old/debian-package-arm64/dependencies.txt | 1 - .../old/debian-package-arm64/docker-build.sh | 21 -- .../old/debian-package-arm64/package.sh | 45 ----- deployment/old/debian-package-arm64/pkg-src | 1 - .../old/debian-package-armhf/Dockerfile.amd64 | 42 ---- .../old/debian-package-armhf/Dockerfile.armhf | 34 ---- deployment/old/debian-package-armhf/clean.sh | 27 --- .../old/debian-package-armhf/dependencies.txt | 1 - .../old/debian-package-armhf/docker-build.sh | 21 -- .../old/debian-package-armhf/package.sh | 45 ----- deployment/old/debian-package-armhf/pkg-src | 1 - deployment/old/debian-package-x64/Dockerfile | 34 ---- deployment/old/debian-package-x64/clean.sh | 27 --- .../old/debian-package-x64/dependencies.txt | 1 - .../old/debian-package-x64/docker-build.sh | 20 -- deployment/old/debian-package-x64/package.sh | 34 ---- .../old/debian-package-x64/pkg-src/changelog | 59 ------ .../old/debian-package-x64/pkg-src/compat | 1 - .../debian-package-x64/pkg-src/conf/jellyfin | 40 ---- .../pkg-src/conf/jellyfin-sudoers | 37 ---- .../pkg-src/conf/jellyfin.service.conf | 7 - .../pkg-src/conf/logging.json | 30 --- .../old/debian-package-x64/pkg-src/control | 31 --- .../old/debian-package-x64/pkg-src/copyright | 29 --- .../old/debian-package-x64/pkg-src/gbp.conf | 6 - .../old/debian-package-x64/pkg-src/install | 6 - .../debian-package-x64/pkg-src/jellyfin.init | 61 ------ .../pkg-src/jellyfin.service | 14 -- .../pkg-src/jellyfin.upstart | 20 -- .../debian-package-x64/pkg-src/po/POTFILES.in | 1 - .../pkg-src/po/templates.pot | 57 ------ .../old/debian-package-x64/pkg-src/postinst | 92 --------- .../old/debian-package-x64/pkg-src/postrm | 81 -------- .../old/debian-package-x64/pkg-src/preinst | 78 -------- .../old/debian-package-x64/pkg-src/prerm | 61 ------ .../old/debian-package-x64/pkg-src/rules | 66 ------- .../pkg-src/source.lintian-overrides | 3 - .../debian-package-x64/pkg-src/source/format | 1 - .../debian-package-x64/pkg-src/source/options | 11 -- deployment/old/fedora-package-x64/Dockerfile | 33 ---- deployment/old/fedora-package-x64/clean.sh | 32 ---- .../old/fedora-package-x64/dependencies.txt | 1 - .../old/fedora-package-x64/docker-build.sh | 18 -- deployment/old/fedora-package-x64/package.sh | 34 ---- .../old/fedora-package-x64/pkg-src/.gitignore | 3 - .../old/fedora-package-x64/pkg-src/README.md | 43 ----- .../pkg-src/jellyfin-firewalld.xml | 9 - .../fedora-package-x64/pkg-src/jellyfin.env | 34 ---- .../pkg-src/jellyfin.override.conf | 7 - .../pkg-src/jellyfin.service | 15 -- .../fedora-package-x64/pkg-src/jellyfin.spec | 181 ------------------ .../pkg-src/jellyfin.sudoers | 19 -- .../old/fedora-package-x64/pkg-src/restart.sh | 36 ---- deployment/old/linux-x64/Dockerfile | 37 ---- deployment/old/linux-x64/clean.sh | 27 --- deployment/old/linux-x64/dependencies.txt | 1 - deployment/old/linux-x64/docker-build.sh | 36 ---- deployment/old/linux-x64/package.sh | 34 ---- deployment/old/macos/Dockerfile | 37 ---- deployment/old/macos/clean.sh | 27 --- deployment/old/macos/dependencies.txt | 1 - deployment/old/macos/docker-build.sh | 36 ---- deployment/old/macos/package.sh | 34 ---- deployment/old/portable/Dockerfile | 37 ---- deployment/old/portable/clean.sh | 27 --- deployment/old/portable/dependencies.txt | 1 - deployment/old/portable/docker-build.sh | 36 ---- deployment/old/portable/package.sh | 34 ---- .../old/ubuntu-package-arm64/Dockerfile.amd64 | 59 ------ .../old/ubuntu-package-arm64/Dockerfile.arm64 | 40 ---- deployment/old/ubuntu-package-arm64/clean.sh | 27 --- .../old/ubuntu-package-arm64/dependencies.txt | 1 - .../old/ubuntu-package-arm64/docker-build.sh | 21 -- .../old/ubuntu-package-arm64/package.sh | 45 ----- deployment/old/ubuntu-package-arm64/pkg-src | 1 - .../old/ubuntu-package-armhf/Dockerfile.amd64 | 59 ------ .../old/ubuntu-package-armhf/Dockerfile.armhf | 40 ---- deployment/old/ubuntu-package-armhf/clean.sh | 27 --- .../old/ubuntu-package-armhf/dependencies.txt | 1 - .../old/ubuntu-package-armhf/docker-build.sh | 21 -- .../old/ubuntu-package-armhf/package.sh | 45 ----- deployment/old/ubuntu-package-armhf/pkg-src | 1 - deployment/old/ubuntu-package-x64/Dockerfile | 36 ---- deployment/old/ubuntu-package-x64/clean.sh | 27 --- .../old/ubuntu-package-x64/dependencies.txt | 1 - .../old/ubuntu-package-x64/docker-build.sh | 20 -- deployment/old/ubuntu-package-x64/package.sh | 34 ---- deployment/old/ubuntu-package-x64/pkg-src | 1 - .../old/unraid/docker-templates/README.md | 15 -- .../old/unraid/docker-templates/jellyfin.xml | 57 ------ deployment/old/win-x64/Dockerfile | 37 ---- deployment/old/win-x64/clean.sh | 27 --- deployment/old/win-x64/dependencies.txt | 1 - deployment/old/win-x64/docker-build.sh | 61 ------ deployment/old/win-x64/package.sh | 34 ---- deployment/old/win-x86/Dockerfile | 37 ---- deployment/old/win-x86/clean.sh | 27 --- deployment/old/win-x86/dependencies.txt | 1 - deployment/old/win-x86/docker-build.sh | 61 ------ deployment/old/win-x86/package.sh | 34 ---- 110 files changed, 3207 deletions(-) delete mode 100644 deployment/old/README.md delete mode 100644 deployment/old/centos-package-x64/Dockerfile delete mode 100755 deployment/old/centos-package-x64/clean.sh delete mode 100644 deployment/old/centos-package-x64/dependencies.txt delete mode 100755 deployment/old/centos-package-x64/docker-build.sh delete mode 100755 deployment/old/centos-package-x64/package.sh delete mode 120000 deployment/old/centos-package-x64/pkg-src delete mode 100644 deployment/old/debian-package-arm64/Dockerfile.amd64 delete mode 100644 deployment/old/debian-package-arm64/Dockerfile.arm64 delete mode 100755 deployment/old/debian-package-arm64/clean.sh delete mode 100644 deployment/old/debian-package-arm64/dependencies.txt delete mode 100755 deployment/old/debian-package-arm64/docker-build.sh delete mode 100755 deployment/old/debian-package-arm64/package.sh delete mode 120000 deployment/old/debian-package-arm64/pkg-src delete mode 100644 deployment/old/debian-package-armhf/Dockerfile.amd64 delete mode 100644 deployment/old/debian-package-armhf/Dockerfile.armhf delete mode 100755 deployment/old/debian-package-armhf/clean.sh delete mode 100644 deployment/old/debian-package-armhf/dependencies.txt delete mode 100755 deployment/old/debian-package-armhf/docker-build.sh delete mode 100755 deployment/old/debian-package-armhf/package.sh delete mode 120000 deployment/old/debian-package-armhf/pkg-src delete mode 100644 deployment/old/debian-package-x64/Dockerfile delete mode 100755 deployment/old/debian-package-x64/clean.sh delete mode 100644 deployment/old/debian-package-x64/dependencies.txt delete mode 100755 deployment/old/debian-package-x64/docker-build.sh delete mode 100755 deployment/old/debian-package-x64/package.sh delete mode 100644 deployment/old/debian-package-x64/pkg-src/changelog delete mode 100644 deployment/old/debian-package-x64/pkg-src/compat delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf delete mode 100644 deployment/old/debian-package-x64/pkg-src/conf/logging.json delete mode 100644 deployment/old/debian-package-x64/pkg-src/control delete mode 100644 deployment/old/debian-package-x64/pkg-src/copyright delete mode 100644 deployment/old/debian-package-x64/pkg-src/gbp.conf delete mode 100644 deployment/old/debian-package-x64/pkg-src/install delete mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.init delete mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.service delete mode 100644 deployment/old/debian-package-x64/pkg-src/jellyfin.upstart delete mode 100644 deployment/old/debian-package-x64/pkg-src/po/POTFILES.in delete mode 100644 deployment/old/debian-package-x64/pkg-src/po/templates.pot delete mode 100644 deployment/old/debian-package-x64/pkg-src/postinst delete mode 100644 deployment/old/debian-package-x64/pkg-src/postrm delete mode 100644 deployment/old/debian-package-x64/pkg-src/preinst delete mode 100644 deployment/old/debian-package-x64/pkg-src/prerm delete mode 100755 deployment/old/debian-package-x64/pkg-src/rules delete mode 100644 deployment/old/debian-package-x64/pkg-src/source.lintian-overrides delete mode 100644 deployment/old/debian-package-x64/pkg-src/source/format delete mode 100644 deployment/old/debian-package-x64/pkg-src/source/options delete mode 100644 deployment/old/fedora-package-x64/Dockerfile delete mode 100755 deployment/old/fedora-package-x64/clean.sh delete mode 100644 deployment/old/fedora-package-x64/dependencies.txt delete mode 100755 deployment/old/fedora-package-x64/docker-build.sh delete mode 100755 deployment/old/fedora-package-x64/package.sh delete mode 100644 deployment/old/fedora-package-x64/pkg-src/.gitignore delete mode 100644 deployment/old/fedora-package-x64/pkg-src/README.md delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.env delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.service delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.spec delete mode 100644 deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers delete mode 100755 deployment/old/fedora-package-x64/pkg-src/restart.sh delete mode 100644 deployment/old/linux-x64/Dockerfile delete mode 100755 deployment/old/linux-x64/clean.sh delete mode 100644 deployment/old/linux-x64/dependencies.txt delete mode 100755 deployment/old/linux-x64/docker-build.sh delete mode 100755 deployment/old/linux-x64/package.sh delete mode 100644 deployment/old/macos/Dockerfile delete mode 100755 deployment/old/macos/clean.sh delete mode 100644 deployment/old/macos/dependencies.txt delete mode 100755 deployment/old/macos/docker-build.sh delete mode 100755 deployment/old/macos/package.sh delete mode 100644 deployment/old/portable/Dockerfile delete mode 100755 deployment/old/portable/clean.sh delete mode 100644 deployment/old/portable/dependencies.txt delete mode 100755 deployment/old/portable/docker-build.sh delete mode 100755 deployment/old/portable/package.sh delete mode 100644 deployment/old/ubuntu-package-arm64/Dockerfile.amd64 delete mode 100644 deployment/old/ubuntu-package-arm64/Dockerfile.arm64 delete mode 100755 deployment/old/ubuntu-package-arm64/clean.sh delete mode 100644 deployment/old/ubuntu-package-arm64/dependencies.txt delete mode 100755 deployment/old/ubuntu-package-arm64/docker-build.sh delete mode 100755 deployment/old/ubuntu-package-arm64/package.sh delete mode 120000 deployment/old/ubuntu-package-arm64/pkg-src delete mode 100644 deployment/old/ubuntu-package-armhf/Dockerfile.amd64 delete mode 100644 deployment/old/ubuntu-package-armhf/Dockerfile.armhf delete mode 100755 deployment/old/ubuntu-package-armhf/clean.sh delete mode 100644 deployment/old/ubuntu-package-armhf/dependencies.txt delete mode 100755 deployment/old/ubuntu-package-armhf/docker-build.sh delete mode 100755 deployment/old/ubuntu-package-armhf/package.sh delete mode 120000 deployment/old/ubuntu-package-armhf/pkg-src delete mode 100644 deployment/old/ubuntu-package-x64/Dockerfile delete mode 100755 deployment/old/ubuntu-package-x64/clean.sh delete mode 100644 deployment/old/ubuntu-package-x64/dependencies.txt delete mode 100755 deployment/old/ubuntu-package-x64/docker-build.sh delete mode 100755 deployment/old/ubuntu-package-x64/package.sh delete mode 120000 deployment/old/ubuntu-package-x64/pkg-src delete mode 100644 deployment/old/unraid/docker-templates/README.md delete mode 100644 deployment/old/unraid/docker-templates/jellyfin.xml delete mode 100644 deployment/old/win-x64/Dockerfile delete mode 100755 deployment/old/win-x64/clean.sh delete mode 100644 deployment/old/win-x64/dependencies.txt delete mode 100755 deployment/old/win-x64/docker-build.sh delete mode 100755 deployment/old/win-x64/package.sh delete mode 100644 deployment/old/win-x86/Dockerfile delete mode 100755 deployment/old/win-x86/clean.sh delete mode 100644 deployment/old/win-x86/dependencies.txt delete mode 100755 deployment/old/win-x86/docker-build.sh delete mode 100755 deployment/old/win-x86/package.sh diff --git a/deployment/old/README.md b/deployment/old/README.md deleted file mode 100644 index a805f59ca3..0000000000 --- a/deployment/old/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Jellyfin Packaging - -This directory contains the packaging configuration of Jellyfin for multiple platforms. The specification is below; all package platforms must follow the specification to be compatable with the central `build` script. - -## Package List - -### Operating System Packages - -* `debian-package-x64`: Package for Debian and Ubuntu amd64 systems. -* `fedora-package-x64`: Package for Fedora, CentOS, and Red Hat Enterprise Linux amd64 systems. - -### Portable Builds (archives) - -* `linux-x64`: Portable binary archive for generic Linux amd64 systems. -* `macos`: Portable binary archive for MacOS amd64 systems. -* `win-x64`: Portable binary archive for Windows amd64 systems. -* `win-x86`: Portable binary archive for Windows i386 systems. - -### Other Builds - -These builds are not necessarily run from the `build` script, but are present for other platforms. - -* `portable`: Compiled `.dll` for use with .NET Core runtime on any system. -* `docker`: Docker manifests for auto-publishing. -* `unraid`: unRaid Docker template; not built by `build` but imported into unRaid directly. -* `windows`: Support files and scripts for Windows CI build. - -## Package Specification - -### Dependencies - -* If a platform requires additional build dependencies, the required binary names, i.e. to validate `which `, should be specified in a `dependencies.txt` file inside the platform directory. - -* Each dependency should be present on its own line. - -### Action Scripts - -* Actions are defined in BASH scripts with the name `.sh` within the platform directory. - -* The list of valid actions are: - - 1. `build`: Builds a set of binaries. - 2. `package`: Assembles the compiled binaries into a package. - 3. `sign`: Performs signing actions on a package. - 4. `publish`: Performs a publishing action for a package. - 5. `clean`: Cleans up any artifacts from the previous actions. - -* All package actions are optional, however at least one should generate output files, and any that do should contain a `clean` action. - -* Actions are executed in the order specified above, and later actions may depend on former actions. - -* Actions except for `clean` should `set -o errexit` to terminate on failed actions. - -* The `clean` action should always `exit 0` even if no work is done or it fails. - -* The `clean` action can be passed a variable as argument 1, named `keep_artifacts`, containing either the value `y` or `n`. It is indended to handle situations when the user runs `build --keep-artifacts` and should be handled intelligently. Usually, this is used to preserve Docker images while still removing temporary directories. - -### Output Files - -* Upon completion of the defined actions, at least one output file must be created in the `/pkg-dist` directory. - -* Output files will be moved to the directory `jellyfin-build/` one directory above the repository root upon completion. diff --git a/deployment/old/centos-package-x64/Dockerfile b/deployment/old/centos-package-x64/Dockerfile deleted file mode 100644 index 08219a2e4a..0000000000 --- a/deployment/old/centos-package-x64/Dockerfile +++ /dev/null @@ -1,39 +0,0 @@ -FROM centos:7 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/centos-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist - -# Prepare CentOS environment -RUN yum update -y \ - && yum install -y epel-release - -# Install build dependencies -RUN yum install -y @buildsys-build rpmdevtools yum-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel git - -# Install recent NodeJS and Yarn -RUN curl -fSsLo /etc/yum.repos.d/yarn.repo https://dl.yarnpkg.com/rpm/yarn.repo \ - && rpm -i https://rpm.nodesource.com/pub_10.x/el/7/x86_64/nodesource-release-el7-1.noarch.rpm \ - && yum install -y yarn - -# Install DotNET SDK -RUN rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm \ - && rpmdev-setuptree \ - && yum install -y dotnet-sdk-${SDK_VERSION} - -# Create symlinks and directories -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ - && mkdir -p ${SOURCE_DIR}/SPECS \ - && ln -s ${PLATFORM_DIR}/pkg-src/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ - && mkdir -p ${SOURCE_DIR}/SOURCES \ - && ln -s ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/SOURCES - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/centos-package-x64/clean.sh b/deployment/old/centos-package-x64/clean.sh deleted file mode 100755 index 31455de0d4..0000000000 --- a/deployment/old/centos-package-x64/clean.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" -VERSION="$( grep -A1 '^Version:' ${WORKDIR}/pkg-src/jellyfin.spec | awk '{ print $NF }' )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -package_source_dir="${WORKDIR}/pkg-src" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-centos-build" - -rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null \ - || sudo rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/centos-package-x64/dependencies.txt b/deployment/old/centos-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/centos-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/centos-package-x64/docker-build.sh b/deployment/old/centos-package-x64/docker-build.sh deleted file mode 100755 index 62dd144e50..0000000000 --- a/deployment/old/centos-package-x64/docker-build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Builds the RPM inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Build RPM -make -f .copr/Makefile srpm outdir=/root/rpmbuild/SRPMS -rpmbuild --rebuild -bb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/rpm -mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/centos-package-x64/package.sh b/deployment/old/centos-package-x64/package.sh deleted file mode 100755 index 1b983f49d9..0000000000 --- a/deployment/old/centos-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-centos-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the RPMs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the RPMs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/rpm/* "${output_dir}" diff --git a/deployment/old/centos-package-x64/pkg-src b/deployment/old/centos-package-x64/pkg-src deleted file mode 120000 index 3ff4d3cbf5..0000000000 --- a/deployment/old/centos-package-x64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../fedora-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/debian-package-arm64/Dockerfile.amd64 b/deployment/old/debian-package-arm64/Dockerfile.amd64 deleted file mode 100644 index b63e08b7dd..0000000000 --- a/deployment/old/debian-package-arm64/Dockerfile.amd64 +++ /dev/null @@ -1,43 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Prepare the cross-toolchain -RUN dpkg --add-architecture arm64 \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="arm64" cross-gcc-gensource 8 \ - && cd cross-gcc-packages-amd64/cross-gcc-8-arm64 \ - && apt-get install -y gcc-8-source libstdc++-8-dev-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 libssl-dev:arm64 liblttng-ust0:arm64 libstdc++-8-dev:arm64 - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] -#ENTRYPOINT ["/bin/bash"] diff --git a/deployment/old/debian-package-arm64/Dockerfile.arm64 b/deployment/old/debian-package-arm64/Dockerfile.arm64 deleted file mode 100644 index 9ca4868441..0000000000 --- a/deployment/old/debian-package-arm64/Dockerfile.arm64 +++ /dev/null @@ -1,34 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=arm64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/5a4c8f96-1c73-401c-a6de-8e100403188a/0ce6ab39747e2508366d498f9c0a0669/dotnet-sdk-3.1.100-linux-arm64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-arm64/clean.sh b/deployment/old/debian-package-arm64/clean.sh deleted file mode 100755 index e7bfdf8b4b..0000000000 --- a/deployment/old/debian-package-arm64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_arm64-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/debian-package-arm64/dependencies.txt b/deployment/old/debian-package-arm64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/debian-package-arm64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/debian-package-arm64/docker-build.sh b/deployment/old/debian-package-arm64/docker-build.sh deleted file mode 100755 index 67ab6bd74b..0000000000 --- a/deployment/old/debian-package-arm64/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarm64 - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-arm64/package.sh b/deployment/old/debian-package-arm64/package.sh deleted file mode 100755 index 2091982187..0000000000 --- a/deployment/old/debian-package-arm64/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_arm64-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.arm64" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-arm64/pkg-src b/deployment/old/debian-package-arm64/pkg-src deleted file mode 120000 index 4c695fea17..0000000000 --- a/deployment/old/debian-package-arm64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/debian-package-armhf/Dockerfile.amd64 b/deployment/old/debian-package-armhf/Dockerfile.amd64 deleted file mode 100644 index 1b64b53148..0000000000 --- a/deployment/old/debian-package-armhf/Dockerfile.amd64 +++ /dev/null @@ -1,42 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Prepare the cross-toolchain -RUN dpkg --add-architecture armhf \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="armhf" cross-gcc-gensource 8 \ - && cd cross-gcc-packages-amd64/cross-gcc-8-armhf \ - && apt-get install -y gcc-8-source libstdc++-8-dev-armhf-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip binutils-arm-linux-gnueabihf libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf libssl-dev:armhf liblttng-ust0:armhf libstdc++-8-dev:armhf - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-armhf/Dockerfile.armhf b/deployment/old/debian-package-armhf/Dockerfile.armhf deleted file mode 100644 index dd398b5aa5..0000000000 --- a/deployment/old/debian-package-armhf/Dockerfile.armhf +++ /dev/null @@ -1,34 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=armhf - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/67766a96-eb8c-4cd2-bca4-ea63d2cc115c/7bf13840aa2ed88793b7315d5e0d74e6/dotnet-sdk-3.1.100-linux-arm.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-armhf/clean.sh b/deployment/old/debian-package-armhf/clean.sh deleted file mode 100755 index 35a3d3e9ad..0000000000 --- a/deployment/old/debian-package-armhf/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_armhf-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/debian-package-armhf/dependencies.txt b/deployment/old/debian-package-armhf/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/debian-package-armhf/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/debian-package-armhf/docker-build.sh b/deployment/old/debian-package-armhf/docker-build.sh deleted file mode 100755 index 1bd7fb2911..0000000000 --- a/deployment/old/debian-package-armhf/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarmhf - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-armhf/package.sh b/deployment/old/debian-package-armhf/package.sh deleted file mode 100755 index 4a27dd8283..0000000000 --- a/deployment/old/debian-package-armhf/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian_armhf-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.armhf" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-armhf/pkg-src b/deployment/old/debian-package-armhf/pkg-src deleted file mode 120000 index 0bb6d55249..0000000000 --- a/deployment/old/debian-package-armhf/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/debian-package-x64/Dockerfile b/deployment/old/debian-package-x64/Dockerfile deleted file mode 100644 index e863d1edf9..0000000000 --- a/deployment/old/debian-package-x64/Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/debian-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget npm devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/debian-package-x64/clean.sh b/deployment/old/debian-package-x64/clean.sh deleted file mode 100755 index 4e507bcb27..0000000000 --- a/deployment/old/debian-package-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/debian-package-x64/dependencies.txt b/deployment/old/debian-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/debian-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/debian-package-x64/docker-build.sh b/deployment/old/debian-package-x64/docker-build.sh deleted file mode 100755 index 962a522ebc..0000000000 --- a/deployment/old/debian-package-x64/docker-build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -dpkg-buildpackage -us -uc - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/debian-package-x64/package.sh b/deployment/old/debian-package-x64/package.sh deleted file mode 100755 index 5a416959ab..0000000000 --- a/deployment/old/debian-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-debian-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/debian-package-x64/pkg-src/changelog b/deployment/old/debian-package-x64/pkg-src/changelog deleted file mode 100644 index 51c4822370..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/changelog +++ /dev/null @@ -1,59 +0,0 @@ -jellyfin (10.5.0-1) unstable; urgency=medium - - * New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 - - -- Jellyfin Packaging Team Fri, 11 Oct 2019 20:12:38 -0400 - -jellyfin (10.4.0-1) unstable; urgency=medium - - * New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 - - -- Jellyfin Packaging Team Sat, 31 Aug 2019 21:38:56 -0400 - -jellyfin (10.3.7-1) unstable; urgency=medium - - * New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 - - -- Jellyfin Packaging Team Wed, 24 Jul 2019 10:48:28 -0400 - -jellyfin (10.3.6-1) unstable; urgency=medium - - * New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 - - -- Jellyfin Packaging Team Sat, 06 Jul 2019 13:34:19 -0400 - -jellyfin (10.3.5-1) unstable; urgency=medium - - * New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 - - -- Jellyfin Packaging Team Sun, 09 Jun 2019 21:47:35 -0400 - -jellyfin (10.3.4-1) unstable; urgency=medium - - * New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 - - -- Jellyfin Packaging Team Thu, 06 Jun 2019 22:45:31 -0400 - -jellyfin (10.3.3-1) unstable; urgency=medium - - * New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 - - -- Jellyfin Packaging Team Fri, 17 May 2019 23:12:08 -0400 - -jellyfin (10.3.2-1) unstable; urgency=medium - - * New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 - - -- Jellyfin Packaging Team Tue, 30 Apr 2019 20:18:44 -0400 - -jellyfin (10.3.1-1) unstable; urgency=medium - - * New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 - - -- Jellyfin Packaging Team Sat, 20 Apr 2019 14:24:07 -0400 - -jellyfin (10.3.0-1) unstable; urgency=medium - - * New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 - - -- Jellyfin Packaging Team Fri, 19 Apr 2019 14:24:29 -0400 diff --git a/deployment/old/debian-package-x64/pkg-src/compat b/deployment/old/debian-package-x64/pkg-src/compat deleted file mode 100644 index 45a4fb75db..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/compat +++ /dev/null @@ -1 +0,0 @@ -8 diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin deleted file mode 100644 index c6e595f15a..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin +++ /dev/null @@ -1,40 +0,0 @@ -# Jellyfin default configuration options -# This is a POSIX shell fragment - -# Use this file to override the default configurations; add additional -# options with JELLYFIN_ADD_OPTS. - -# Under systemd, use -# /etc/systemd/system/jellyfin.service.d/jellyfin.service.conf -# to override the user or this config file's location. - -# -# General options -# - -# Program directories -JELLYFIN_DATA_DIR="/var/lib/jellyfin" -JELLYFIN_CONFIG_DIR="/etc/jellyfin" -JELLYFIN_LOG_DIR="/var/log/jellyfin" -JELLYFIN_CACHE_DIR="/var/cache/jellyfin" - -# Restart script for in-app server control -JELLYFIN_RESTART_OPT="--restartpath=/usr/lib/jellyfin/restart.sh" - -# ffmpeg binary paths, overriding the system values -JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/lib/jellyfin-ffmpeg/ffmpeg" - -# [OPTIONAL] run Jellyfin as a headless service -#JELLYFIN_SERVICE_OPT="--service" - -# [OPTIONAL] run Jellyfin without the web app -#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" - -# -# SysV init/Upstart options -# - -# Application username -JELLYFIN_USER="jellyfin" -# Full application command -JELLYFIN_ARGS="$JELLYFIN_RESTART_OPT $JELLYFIN_FFMPEG_OPT $JELLYFIN_SERVICE_OPT $JELLFIN_NOWEBAPP_OPT" diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers deleted file mode 100644 index b481ba4ad4..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin-sudoers +++ /dev/null @@ -1,37 +0,0 @@ -#Allow jellyfin group to start, stop and restart itself -Cmnd_Alias RESTARTSERVER_SYSV = /sbin/service jellyfin restart, /usr/sbin/service jellyfin restart -Cmnd_Alias STARTSERVER_SYSV = /sbin/service jellyfin start, /usr/sbin/service jellyfin start -Cmnd_Alias STOPSERVER_SYSV = /sbin/service jellyfin stop, /usr/sbin/service jellyfin stop -Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin -Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin -Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin -Cmnd_Alias RESTARTSERVER_INITD = /etc/init.d/jellyfin restart -Cmnd_Alias STARTSERVER_INITD = /etc/init.d/jellyfin start -Cmnd_Alias STOPSERVER_INITD = /etc/init.d/jellyfin stop - - -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSV -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSV -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSV -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_INITD -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_INITD -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_INITD - -Defaults!RESTARTSERVER_SYSV !requiretty -Defaults!STARTSERVER_SYSV !requiretty -Defaults!STOPSERVER_SYSV !requiretty -Defaults!RESTARTSERVER_SYSTEMD !requiretty -Defaults!STARTSERVER_SYSTEMD !requiretty -Defaults!STOPSERVER_SYSTEMD !requiretty -Defaults!RESTARTSERVER_INITD !requiretty -Defaults!STARTSERVER_INITD !requiretty -Defaults!STOPSERVER_INITD !requiretty - -#Allow the server to mount iso images -jellyfin ALL=(ALL) NOPASSWD: /bin/mount -jellyfin ALL=(ALL) NOPASSWD: /bin/umount - -Defaults:jellyfin !requiretty diff --git a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf b/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf deleted file mode 100644 index 1b69dd74ef..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/jellyfin.service.conf +++ /dev/null @@ -1,7 +0,0 @@ -# Jellyfin systemd configuration options - -# Use this file to override the user or environment file location. - -[Service] -#User = jellyfin -#EnvironmentFile = /etc/default/jellyfin diff --git a/deployment/old/debian-package-x64/pkg-src/conf/logging.json b/deployment/old/debian-package-x64/pkg-src/conf/logging.json deleted file mode 100644 index f32b2089eb..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/conf/logging.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "Serilog": { - "MinimumLevel": "Information", - "WriteTo": [ - { - "Name": "Console", - "Args": { - "outputTemplate": "[{Timestamp:HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}" - } - }, - { - "Name": "Async", - "Args": { - "configure": [ - { - "Name": "File", - "Args": { - "path": "%JELLYFIN_LOG_DIR%//jellyfin.log", - "fileSizeLimitBytes": 10485700, - "rollOnFileSizeLimit": true, - "retainedFileCountLimit": 10, - "outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] {Message}{NewLine}{Exception}" - } - } - ] - } - } - ] - } -} diff --git a/deployment/old/debian-package-x64/pkg-src/control b/deployment/old/debian-package-x64/pkg-src/control deleted file mode 100644 index 13fd3ecabb..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/control +++ /dev/null @@ -1,31 +0,0 @@ -Source: jellyfin -Section: misc -Priority: optional -Maintainer: Jellyfin Team -Build-Depends: debhelper (>= 9), - dotnet-sdk-3.1, - libc6-dev, - libcurl4-openssl-dev, - libfontconfig1-dev, - libfreetype6-dev, - libssl-dev, - wget, - npm | nodejs -Standards-Version: 3.9.4 -Homepage: https://jellyfin.media/ -Vcs-Git: https://github.org/jellyfin/jellyfin.git -Vcs-Browser: https://github.org/jellyfin/jellyfin - -Package: jellyfin -Replaces: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server -Breaks: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server -Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server -Architecture: any -Depends: at, - libsqlite3-0, - jellyfin-ffmpeg, - libfontconfig1, - libfreetype6, - libssl1.1 -Description: Jellyfin is a home media server. - It is built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono. It features a REST-based api with built-in documentation to facilitate client development. We also have client libraries for our api to enable rapid development. diff --git a/deployment/old/debian-package-x64/pkg-src/copyright b/deployment/old/debian-package-x64/pkg-src/copyright deleted file mode 100644 index 0d7a2a6007..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/copyright +++ /dev/null @@ -1,29 +0,0 @@ -Format: http://dep.debian.net/deps/dep5 -Upstream-Name: jellyfin -Source: https://github.com/jellyfin/jellyfin - -Files: * -Copyright: 2018 Jellyfin Team -License: GPL-2.0+ - -Files: debian/* -Copyright: 2018 Joshua Boniface -Copyright: 2014 Carlos Hernandez -License: GPL-2.0+ - -License: GPL-2.0+ - This package is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License - along with this program. If not, see - . - On Debian systems, the complete text of the GNU General - Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/deployment/old/debian-package-x64/pkg-src/gbp.conf b/deployment/old/debian-package-x64/pkg-src/gbp.conf deleted file mode 100644 index 60b3d28723..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/gbp.conf +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -pristine-tar = False -cleaner = fakeroot debian/rules clean - -[import-orig] -filter = [ ".git*", ".hg*", ".vs*", ".vscode*" ] diff --git a/deployment/old/debian-package-x64/pkg-src/install b/deployment/old/debian-package-x64/pkg-src/install deleted file mode 100644 index 994322d141..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/install +++ /dev/null @@ -1,6 +0,0 @@ -usr/lib/jellyfin usr/lib/ -debian/conf/jellyfin etc/default/ -debian/conf/logging.json etc/jellyfin/ -debian/conf/jellyfin.service.conf etc/systemd/system/jellyfin.service.d/ -debian/conf/jellyfin-sudoers etc/sudoers.d/ -debian/bin/restart.sh usr/lib/jellyfin/ diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.init b/deployment/old/debian-package-x64/pkg-src/jellyfin.init deleted file mode 100644 index 7f5642bac1..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/jellyfin.init +++ /dev/null @@ -1,61 +0,0 @@ -### BEGIN INIT INFO -# Provides: Jellyfin Media Server -# Required-Start: $local_fs $network -# Required-Stop: $local_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Jellyfin Media Server -# Description: Runs Jellyfin Server -### END INIT INFO - -set -e - -# Carry out specific functions when asked to by the system - -if test -f /etc/default/jellyfin; then - . /etc/default/jellyfin -fi - -. /lib/lsb/init-functions - -PIDFILE="/run/jellyfin.pid" - -case "$1" in - start) - log_daemon_msg "Starting Jellyfin Media Server" "jellyfin" || true - - if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then - log_end_msg 0 || true - else - log_end_msg 1 || true - fi - ;; - - stop) - log_daemon_msg "Stopping Jellyfin Media Server" "jellyfin" || true - if start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE --remove-pidfile; then - log_end_msg 0 || true - else - log_end_msg 1 || true - fi - ;; - - restart) - log_daemon_msg "Restarting Jellyfin Media Server" "jellyfin" || true - start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile $PIDFILE --remove-pidfile - if start-stop-daemon --start --quiet --oknodo --background --pidfile $PIDFILE --make-pidfile --user $JELLYFIN_USER --chuid $JELLYFIN_USER --exec /usr/bin/jellyfin -- $JELLYFIN_ARGS; then - log_end_msg 0 || true - else - log_end_msg 1 || true - fi - ;; - - status) - status_of_proc -p $PIDFILE /usr/bin/jellyfin jellyfin && exit 0 || exit $? - ;; - - *) - echo "Usage: $0 {start|stop|restart|status}" - exit 1 - ;; -esac diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.service b/deployment/old/debian-package-x64/pkg-src/jellyfin.service deleted file mode 100644 index 1305e238b0..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/jellyfin.service +++ /dev/null @@ -1,14 +0,0 @@ -[Unit] -Description = Jellyfin Media Server -After = network.target - -[Service] -Type = simple -EnvironmentFile = /etc/default/jellyfin -User = jellyfin -ExecStart = /usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} -Restart = on-failure -TimeoutSec = 15 - -[Install] -WantedBy = multi-user.target diff --git a/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart b/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart deleted file mode 100644 index ef5bc9bcaf..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/jellyfin.upstart +++ /dev/null @@ -1,20 +0,0 @@ -description "jellyfin daemon" - -start on (local-filesystems and net-device-up IFACE!=lo) -stop on runlevel [!2345] - -console log -respawn -respawn limit 10 5 - -kill timeout 20 - -script - set -x - echo "Starting $UPSTART_JOB" - - # Log file - logger -t "$0" "DEBUG: `set`" - . /etc/default/jellyfin - exec su -u $JELLYFIN_USER -c /usr/bin/jellyfin $JELLYFIN_ARGS -end script diff --git a/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in b/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in deleted file mode 100644 index cef83a3407..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/po/POTFILES.in +++ /dev/null @@ -1 +0,0 @@ -[type: gettext/rfc822deb] templates diff --git a/deployment/old/debian-package-x64/pkg-src/po/templates.pot b/deployment/old/debian-package-x64/pkg-src/po/templates.pot deleted file mode 100644 index 2cdcae4173..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/po/templates.pot +++ /dev/null @@ -1,57 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR , YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: jellyfin-server\n" -"Report-Msgid-Bugs-To: jellyfin-server@packages.debian.org\n" -"POT-Creation-Date: 2015-06-12 20:51-0600\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" -"Language-Team: LANGUAGE \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=CHARSET\n" -"Content-Transfer-Encoding: 8bit\n" - -#. Type: note -#. Description -#: ../templates:1001 -msgid "Jellyfin permission info:" -msgstr "" - -#. Type: note -#. Description -#: ../templates:1001 -msgid "" -"Jellyfin by default runs under a user named \"jellyfin\". Please ensure that the " -"user jellyfin has read and write access to any folders you wish to add to your " -"library. Otherwise please run jellyfin under a different user." -msgstr "" - -#. Type: string -#. Description -#: ../templates:2001 -msgid "Username to run Jellyfin as:" -msgstr "" - -#. Type: string -#. Description -#: ../templates:2001 -msgid "The user that jellyfin will run as." -msgstr "" - -#. Type: note -#. Description -#: ../templates:3001 -msgid "Jellyfin still running" -msgstr "" - -#. Type: note -#. Description -#: ../templates:3001 -msgid "Jellyfin is currently running. Please close it and try again." -msgstr "" diff --git a/deployment/old/debian-package-x64/pkg-src/postinst b/deployment/old/debian-package-x64/pkg-src/postinst deleted file mode 100644 index 860222e051..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/postinst +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -case "$1" in - configure) - # create jellyfin group if it does not exist - if [[ -z "$(getent group jellyfin)" ]]; then - addgroup --quiet --system jellyfin > /dev/null 2>&1 - fi - # create jellyfin user if it does not exist - if [[ -z "$(getent passwd jellyfin)" ]]; then - adduser --system --ingroup jellyfin --shell /bin/false jellyfin --no-create-home --home ${PROGRAMDATA} \ - --gecos "Jellyfin default user" > /dev/null 2>&1 - fi - # ensure $PROGRAMDATA exists - if [[ ! -d $PROGRAMDATA ]]; then - mkdir $PROGRAMDATA - fi - # ensure $CONFIGDATA exists - if [[ ! -d $CONFIGDATA ]]; then - mkdir $CONFIGDATA - fi - # ensure $LOGDATA exists - if [[ ! -d $LOGDATA ]]; then - mkdir $LOGDATA - fi - # ensure $CACHEDATA exists - if [[ ! -d $CACHEDATA ]]; then - mkdir $CACHEDATA - fi - # Ensure permissions are correct on all config directories - chown -R jellyfin $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA - chgrp adm $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA - chmod 0750 $PROGRAMDATA $CONFIGDATA $LOGDATA $CACHEDATA - - chmod +x /usr/lib/jellyfin/restart.sh > /dev/null 2>&1 || true - - # Install jellyfin symlink into /usr/bin - ln -sf /usr/lib/jellyfin/bin/jellyfin /usr/bin/jellyfin - - ;; - abort-upgrade|abort-remove|abort-deconfigure) - ;; - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER - -if [[ -x "/usr/bin/deb-systemd-helper" ]]; then - # Manual init script handling - deb-systemd-helper unmask jellyfin.service >/dev/null || true - # was-enabled defaults to true, so new installations run enable. - if deb-systemd-helper --quiet was-enabled jellyfin.service; then - # Enables the unit on first installation, creates new - # symlinks on upgrades if the unit file has changed. - deb-systemd-helper enable jellyfin.service >/dev/null || true - else - # Update the statefile to add new symlinks (if any), which need to be - # cleaned up on purge. Also remove old symlinks. - deb-systemd-helper update-state jellyfin.service >/dev/null || true - fi -fi - -# End automatically added section -# Automatically added by dh_installinit -if [[ "$1" == "configure" ]] || [[ "$1" == "abort-upgrade" ]]; then - if [[ -d "/run/systemd/systemd" ]]; then - systemctl --system daemon-reload >/dev/null || true - deb-systemd-invoke start jellyfin >/dev/null || true - elif [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.conf" ]]; then - update-rc.d jellyfin defaults >/dev/null - invoke-rc.d jellyfin start || exit $? - fi -fi -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/postrm b/deployment/old/debian-package-x64/pkg-src/postrm deleted file mode 100644 index 1d00a984ec..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/postrm +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -# In case this system is running systemd, we make systemd reload the unit files -# to pick up changes. -if [[ -d /run/systemd/system ]] ; then - systemctl --system daemon-reload >/dev/null || true -fi - -case "$1" in - purge) - echo PURGE | debconf-communicate $NAME > /dev/null 2>&1 || true - - if [[ -x "/etc/init.d/jellyfin" ]] || [[ -e "/etc/init/jellyfin.connf" ]]; then - update-rc.d jellyfin remove >/dev/null 2>&1 || true - fi - - if [[ -x "/usr/bin/deb-systemd-helper" ]]; then - deb-systemd-helper purge jellyfin.service >/dev/null - deb-systemd-helper unmask jellyfin.service >/dev/null - fi - - # Remove user and group - userdel jellyfin > /dev/null 2>&1 || true - delgroup --quiet jellyfin > /dev/null 2>&1 || true - # Remove config dir - if [[ -d $CONFIGDATA ]]; then - rm -rf $CONFIGDATA - fi - # Remove log dir - if [[ -d $LOGDATA ]]; then - rm -rf $LOGDATA - fi - # Remove cache dir - if [[ -d $CACHEDATA ]]; then - rm -rf $CACHEDATA - fi - # Remove program data dir - if [[ -d $PROGRAMDATA ]]; then - rm -rf $PROGRAMDATA - fi - # Remove binary symlink - [[ -f /usr/bin/jellyfin ]] && rm /usr/bin/jellyfin - # Remove sudoers config - [[ -f /etc/sudoers.d/jellyfin-sudoers ]] && rm /etc/sudoers.d/jellyfin-sudoers - # Remove anything at the default locations; catches situations where the user moved the defaults - [[ -e /etc/jellyfin ]] && rm -rf /etc/jellyfin - [[ -e /var/log/jellyfin ]] && rm -rf /var/log/jellyfin - [[ -e /var/cache/jellyfin ]] && rm -rf /var/cache/jellyfin - [[ -e /var/lib/jellyfin ]] && rm -rf /var/lib/jellyfin - ;; - remove) - if [[ -x "/usr/bin/deb-systemd-helper" ]]; then - deb-systemd-helper mask jellyfin.service >/dev/null - fi - ;; - upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/preinst b/deployment/old/debian-package-x64/pkg-src/preinst deleted file mode 100644 index 2713fb9b80..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/preinst +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -# In case this system is running systemd, we make systemd reload the unit files -# to pick up changes. -if [[ -d /run/systemd/system ]] ; then - systemctl --system daemon-reload >/dev/null || true -fi - -case "$1" in - install|upgrade) - # try graceful termination; - if [[ -d /run/systemd/system ]]; then - deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true - elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then - invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true - fi - # try and figure out if jellyfin is running - PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) - [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) - # if its running, let's stop it - if [[ -n "$JELLYFIN_PID" ]]; then - echo "Stopping Jellyfin!" - # if jellyfin is still running, kill it - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - CPIDS=$(pgrep -P $JELLYFIN_PID) - sleep 2 && kill -KILL $CPIDS - kill -TERM $CPIDS > /dev/null 2>&1 - fi - sleep 1 - # if it's still running, show error - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - echo "Could not successfully stop JellyfinServer, please do so before uninstalling." - exit 1 - else - [[ -f $PIDFILE ]] && rm $PIDFILE - fi - fi - - # Clean up old Emby cruft that can break the user's system - [[ -f /etc/sudoers.d/emby ]] && rm -f /etc/sudoers.d/emby - - # If we have existing config, log, or cache dirs in /var/lib/jellyfin, move them into the right place - if [[ -d $PROGRAMDATA/config ]]; then - mv $PROGRAMDATA/config $CONFIGDATA - fi - if [[ -d $PROGRAMDATA/logs ]]; then - mv $PROGRAMDATA/logs $LOGDATA - fi - if [[ -d $PROGRAMDATA/logs ]]; then - mv $PROGRAMDATA/cache $CACHEDATA - fi - - ;; - abort-upgrade) - ;; - *) - echo "preinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac -#DEBHELPER# - -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/prerm b/deployment/old/debian-package-x64/pkg-src/prerm deleted file mode 100644 index e965cb7d71..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/prerm +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -set -e - -NAME=jellyfin -DEFAULT_FILE=/etc/default/${NAME} - -# Source Jellyfin default configuration -if [[ -f $DEFAULT_FILE ]]; then - . $DEFAULT_FILE -fi - -# Data directories for program data (cache, db), configs, and logs -PROGRAMDATA=${JELLYFIN_DATA_DIRECTORY-/var/lib/$NAME} -CONFIGDATA=${JELLYFIN_CONFIG_DIRECTORY-/etc/$NAME} -LOGDATA=${JELLYFIN_LOG_DIRECTORY-/var/log/$NAME} -CACHEDATA=${JELLYFIN_CACHE_DIRECTORY-/var/cache/$NAME} - -case "$1" in - remove|upgrade|deconfigure) - echo "Stopping Jellyfin!" - # try graceful termination; - if [[ -d /run/systemd/system ]]; then - deb-systemd-invoke stop ${NAME}.service > /dev/null 2>&1 || true - elif [ -x "/etc/init.d/${NAME}" ] || [ -e "/etc/init/${NAME}.conf" ]; then - invoke-rc.d ${NAME} stop > /dev/null 2>&1 || true - fi - # Ensure that it is shutdown - PIDFILE=$(find /var/run/ -maxdepth 1 -mindepth 1 -name "jellyfin*.pid" -print -quit) - [[ -n "$PIDFILE" ]] && [[ -s "$PIDFILE" ]] && JELLYFIN_PID=$(cat ${PIDFILE}) - # if its running, let's stop it - if [[ -n "$JELLYFIN_PID" ]]; then - # if jellyfin is still running, kill it - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - CPIDS=$(pgrep -P $JELLYFIN_PID) - sleep 2 && kill -KILL $CPIDS - kill -TERM $CPIDS > /dev/null 2>&1 - fi - sleep 1 - # if it's still running, show error - if [[ -n "$(ps -p $JELLYFIN_PID -o pid=)" ]]; then - echo "Could not successfully stop Jellyfin, please do so before uninstalling." - exit 1 - else - [[ -f $PIDFILE ]] && rm $PIDFILE - fi - fi - if [[ -f /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so ]]; then - rm /usr/lib/jellyfin/bin/MediaBrowser.Server.Mono.exe.so - fi - ;; - failed-upgrade) - ;; - *) - echo "prerm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -#DEBHELPER# - -exit 0 diff --git a/deployment/old/debian-package-x64/pkg-src/rules b/deployment/old/debian-package-x64/pkg-src/rules deleted file mode 100755 index c2d57dfb22..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/rules +++ /dev/null @@ -1,66 +0,0 @@ -#! /usr/bin/make -f -CONFIG := Release -TERM := xterm -SHELL := /bin/bash -WEB_TARGET := $(CURDIR)/MediaBrowser.WebDashboard/jellyfin-web -WEB_VERSION := $(shell sed -n -e 's/^version: "\(.*\)"/\1/p' $(CURDIR)/build.yaml) - -HOST_ARCH := $(shell arch) -BUILD_ARCH := ${DEB_HOST_MULTIARCH} -ifeq ($(HOST_ARCH),x86_64) - # Building AMD64 - DOTNETRUNTIME := debian-x64 - ifeq ($(BUILD_ARCH),arm-linux-gnueabihf) - # Cross-building ARM on AMD64 - DOTNETRUNTIME := debian-arm - endif - ifeq ($(BUILD_ARCH),aarch64-linux-gnu) - # Cross-building ARM on AMD64 - DOTNETRUNTIME := debian-arm64 - endif -endif -ifeq ($(HOST_ARCH),armv7l) - # Building ARM - DOTNETRUNTIME := debian-arm -endif -ifeq ($(HOST_ARCH),arm64) - # Building ARM - DOTNETRUNTIME := debian-arm64 -endif - -export DH_VERBOSE=1 -export DOTNET_CLI_TELEMETRY_OPTOUT=1 - -%: - dh $@ - -# disable "make check" -override_dh_auto_test: - -# disable stripping debugging symbols -override_dh_clistrip: - -override_dh_auto_build: - echo $(WEB_VERSION) - # Clone down and build Web frontend - mkdir -p $(WEB_TARGET) - wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/v$(WEB_VERSION).tar.gz || wget -O web-src.tgz https://github.com/jellyfin/jellyfin-web/archive/master.tar.gz - mkdir -p $(CURDIR)/web - tar -xzf web-src.tgz -C $(CURDIR)/web/ --strip 1 - cd $(CURDIR)/web/ && npm install yarn - cd $(CURDIR)/web/ && node_modules/yarn/bin/yarn install - mv $(CURDIR)/web/dist/* $(WEB_TARGET)/ - # Build the application - dotnet publish --configuration $(CONFIG) --output='$(CURDIR)/usr/lib/jellyfin/bin' --self-contained --runtime $(DOTNETRUNTIME) \ - "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server - -override_dh_auto_clean: - dotnet clean -maxcpucount:1 --configuration $(CONFIG) Jellyfin.Server || true - rm -f '$(CURDIR)/web-src.tgz' - rm -rf '$(CURDIR)/usr' - rm -rf '$(CURDIR)/web' - rm -rf '$(WEB_TARGET)' - -# Force the service name to jellyfin even if we're building jellyfin-nightly -override_dh_installinit: - dh_installinit --name=jellyfin diff --git a/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides b/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides deleted file mode 100644 index aeb332f13a..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/source.lintian-overrides +++ /dev/null @@ -1,3 +0,0 @@ -# This is an override for the following lintian errors: -jellyfin source: license-problem-md5sum-non-free-file Emby.Drawing/ImageMagick/fonts/webdings.ttf* -jellyfin source: source-is-missing diff --git a/deployment/old/debian-package-x64/pkg-src/source/format b/deployment/old/debian-package-x64/pkg-src/source/format deleted file mode 100644 index d3827e75a5..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/source/format +++ /dev/null @@ -1 +0,0 @@ -1.0 diff --git a/deployment/old/debian-package-x64/pkg-src/source/options b/deployment/old/debian-package-x64/pkg-src/source/options deleted file mode 100644 index 17b5373d5e..0000000000 --- a/deployment/old/debian-package-x64/pkg-src/source/options +++ /dev/null @@ -1,11 +0,0 @@ -tar-ignore='.git*' -tar-ignore='**/.git' -tar-ignore='**/.hg' -tar-ignore='**/.vs' -tar-ignore='**/.vscode' -tar-ignore='deployment' -tar-ignore='**/bin' -tar-ignore='**/obj' -tar-ignore='**/.nuget' -tar-ignore='*.deb' -tar-ignore='ThirdParty' diff --git a/deployment/old/fedora-package-x64/Dockerfile b/deployment/old/fedora-package-x64/Dockerfile deleted file mode 100644 index 87120f3a05..0000000000 --- a/deployment/old/fedora-package-x64/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM fedora:31 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/fedora-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist - -# Prepare Fedora environment -RUN dnf update -y - -# Install build dependencies -RUN dnf install -y @buildsys-build rpmdevtools git dnf-plugins-core libcurl-devel fontconfig-devel freetype-devel openssl-devel glibc-devel libicu-devel nodejs-yarn - -# Install DotNET SDK -RUN rpm --import https://packages.microsoft.com/keys/microsoft.asc \ - && curl -o /etc/yum.repos.d/microsoft-prod.repo https://packages.microsoft.com/config/fedora/$(rpm -E %fedora)/prod.repo \ - && dnf install -y dotnet-sdk-${SDK_VERSION} dotnet-runtime-${SDK_VERSION} - -# Create symlinks and directories -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ - && mkdir -p ${SOURCE_DIR}/SPECS \ - && ln -s ${PLATFORM_DIR}/pkg-src/jellyfin.spec ${SOURCE_DIR}/SPECS/jellyfin.spec \ - && mkdir -p ${SOURCE_DIR}/SOURCES \ - && ln -s ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/SOURCES - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/fedora-package-x64/clean.sh b/deployment/old/fedora-package-x64/clean.sh deleted file mode 100755 index 700c8f1bb3..0000000000 --- a/deployment/old/fedora-package-x64/clean.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" -VERSION="$( grep -A1 '^Version:' ${WORKDIR}/pkg-src/jellyfin.spec | awk '{ print $NF }' )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -package_source_dir="${WORKDIR}/pkg-src" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-fedora-build" - -rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null \ - || sudo rm -f "${package_source_dir}/jellyfin-${VERSION}.tar.gz" &>/dev/null - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/fedora-package-x64/dependencies.txt b/deployment/old/fedora-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/fedora-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/fedora-package-x64/docker-build.sh b/deployment/old/fedora-package-x64/docker-build.sh deleted file mode 100755 index 740e8d35ca..0000000000 --- a/deployment/old/fedora-package-x64/docker-build.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# Builds the RPM inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Build RPM -make -f .copr/Makefile srpm outdir=/root/rpmbuild/SRPMS -rpmbuild -rb /root/rpmbuild/SRPMS/jellyfin-*.src.rpm - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/rpm -mv /root/rpmbuild/RPMS/x86_64/jellyfin-*.rpm /root/rpmbuild/SRPMS/jellyfin-*.src.rpm ${ARTIFACT_DIR}/rpm/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/fedora-package-x64/package.sh b/deployment/old/fedora-package-x64/package.sh deleted file mode 100755 index ae6962dd1f..0000000000 --- a/deployment/old/fedora-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-fedora-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the RPMs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the RPMs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/rpm/* "${output_dir}" diff --git a/deployment/old/fedora-package-x64/pkg-src/.gitignore b/deployment/old/fedora-package-x64/pkg-src/.gitignore deleted file mode 100644 index 6019b98c22..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.rpm -*.zip -*.tar.gz \ No newline at end of file diff --git a/deployment/old/fedora-package-x64/pkg-src/README.md b/deployment/old/fedora-package-x64/pkg-src/README.md deleted file mode 100644 index 7ed6f7efc6..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Jellyfin RPM - -## Build Fedora Package with docker - -Change into this directory `cd rpm-package` -Run the build script `./build-fedora-rpm.sh`. -Resulting RPM and src.rpm will be in `../../jellyfin-*.rpm` - -## ffmpeg - -The RPM package for Fedora/CentOS requires some additional repositories as ffmpeg is not in the main repositories. - -```shell -# ffmpeg from RPMfusion free -# Fedora -$ sudo dnf install https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm -# CentOS 7 -$ sudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm -``` - -## ISO mounting - -To allow Jellyfin to mount/umount ISO files uncomment these two lines in `/etc/sudoers.d/jellyfin-sudoers` -``` -# %jellyfin ALL=(ALL) NOPASSWD: /bin/mount -# %jellyfin ALL=(ALL) NOPASSWD: /bin/umount -``` - -## Building with dotnet - -Jellyfin is build with `--self-contained` so no dotnet required for runtime. - -```shell -# dotnet required for building the RPM -# Fedora -$ sudo dnf copr enable @dotnet-sig/dotnet -# CentOS -$ sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm -``` - -## TODO - -- [ ] OpenSUSE \ No newline at end of file diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml b/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml deleted file mode 100644 index 538c5d65f8..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin-firewalld.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - Jellyfin - The Free Software Media System. - - - - - diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.env b/deployment/old/fedora-package-x64/pkg-src/jellyfin.env deleted file mode 100644 index de48f13af5..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.env +++ /dev/null @@ -1,34 +0,0 @@ -# Jellyfin default configuration options - -# Use this file to override the default configurations; add additional -# options with JELLYFIN_ADD_OPTS. - -# To override the user or this config file's location, use -# /etc/systemd/system/jellyfin.service.d/override.conf - -# -# This is a POSIX shell fragment -# - -# -# General options -# - -# Program directories -JELLYFIN_DATA_DIR="/var/lib/jellyfin" -JELLYFIN_CONFIG_DIR="/etc/jellyfin" -JELLYFIN_LOG_DIR="/var/log/jellyfin" -JELLYFIN_CACHE_DIR="/var/cache/jellyfin" - -# In-App service control -JELLYFIN_RESTART_OPT="--restartpath=/usr/libexec/jellyfin/restart.sh" - -# [OPTIONAL] ffmpeg binary paths, overriding the UI-configured values -#JELLYFIN_FFMPEG_OPT="--ffmpeg=/usr/bin/ffmpeg" - -# [OPTIONAL] run Jellyfin as a headless service -#JELLYFIN_SERVICE_OPT="--service" - -# [OPTIONAL] run Jellyfin without the web app -#JELLYFIN_NOWEBAPP_OPT="--noautorunwebapp" - diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf b/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf deleted file mode 100644 index 8652450bb4..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.override.conf +++ /dev/null @@ -1,7 +0,0 @@ -# Jellyfin systemd configuration options - -# Use this file to override the user or environment file location. - -[Service] -#User = jellyfin -#EnvironmentFile = /etc/sysconfig/jellyfin diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.service b/deployment/old/fedora-package-x64/pkg-src/jellyfin.service deleted file mode 100644 index f3dc594b1c..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.service +++ /dev/null @@ -1,15 +0,0 @@ -[Unit] -After=network.target -Description=Jellyfin is a free software media system that puts you in control of managing and streaming your media. - -[Service] -EnvironmentFile=/etc/sysconfig/jellyfin -WorkingDirectory=/var/lib/jellyfin -ExecStart=/usr/bin/jellyfin ${JELLYFIN_RESTART_OPT} ${JELLYFIN_FFMPEG_OPT} ${JELLYFIN_SERVICE_OPT} ${JELLYFIN_NOWEBAPP_OPT} -TimeoutSec=15 -Restart=on-failure -User=jellyfin -Group=jellyfin - -[Install] -WantedBy=multi-user.target diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec b/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec deleted file mode 100644 index 33c6f6f648..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.spec +++ /dev/null @@ -1,181 +0,0 @@ -%global debug_package %{nil} -# Set the dotnet runtime -%if 0%{?fedora} -%global dotnet_runtime fedora-x64 -%else -%global dotnet_runtime centos-x64 -%endif - -Name: jellyfin -Version: 10.5.0 -Release: 1%{?dist} -Summary: The Free Software Media Browser -License: GPLv2 -URL: https://jellyfin.media -# Jellyfin Server tarball created by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` -Source0: https://github.com/%{name}/%{name}/archive/%{name}-%{version}.tar.gz -# Jellyfin Webinterface downloaded by `make -f .copr/Makefile srpm`, real URL ends with `v%{version}.tar.gz` -Source1: https://github.com/%{name}/%{name}-web/archive/%{name}-web-%{version}.tar.gz -Source11: jellyfin.service -Source12: jellyfin.env -Source13: jellyfin.sudoers -Source14: restart.sh -Source15: jellyfin.override.conf -Source16: jellyfin-firewalld.xml - -%{?systemd_requires} -BuildRequires: systemd -Requires(pre): shadow-utils -BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel, glibc-devel, libicu-devel, git -%if 0%{?fedora} -BuildRequires: nodejs-yarn, git -%else -# Requirements not packaged in main repos -# From https://rpm.nodesource.com/pub_10.x/el/7/x86_64/ -BuildRequires: nodejs >= 10 yarn -%endif -Requires: libcurl, fontconfig, freetype, openssl, glibc libicu -# Requirements not packaged in main repos -# COPR @dotnet-sig/dotnet or -# https://packages.microsoft.com/rhel/7/prod/ -BuildRequires: dotnet-runtime-3.1, dotnet-sdk-3.1 -# RPMfusion free -Requires: ffmpeg - -# Disable Automatic Dependency Processing -AutoReqProv: no - -%description -Jellyfin is a free software media system that puts you in control of managing and streaming your media. - - -%prep -%autosetup -n %{name}-%{version} -b 0 -b 1 -web_build_dir="$(mktemp -d)" -web_target="$PWD/MediaBrowser.WebDashboard/jellyfin-web" -pushd ../jellyfin-web-%{version} || pushd ../jellyfin-web-master -%if 0%{?fedora} -nodejs-yarn install -%else -yarn install -%endif -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd - -%build - -%install -export DOTNET_CLI_TELEMETRY_OPTOUT=1 -export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -dotnet publish --configuration Release --output='%{buildroot}%{_libdir}/jellyfin' --self-contained --runtime %{dotnet_runtime} \ - "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" Jellyfin.Server -%{__install} -D -m 0644 LICENSE %{buildroot}%{_datadir}/licenses/%{name}/LICENSE -%{__install} -D -m 0644 %{SOURCE15} %{buildroot}%{_sysconfdir}/systemd/system/%{name}.service.d/override.conf -%{__install} -D -m 0644 Jellyfin.Server/Resources/Configuration/logging.json %{buildroot}%{_sysconfdir}/%{name}/logging.json -%{__mkdir} -p %{buildroot}%{_bindir} -tee %{buildroot}%{_bindir}/jellyfin << EOF -#!/bin/sh -exec %{_libdir}/%{name}/%{name} \${@} -EOF -%{__mkdir} -p %{buildroot}%{_sharedstatedir}/jellyfin -%{__mkdir} -p %{buildroot}%{_sysconfdir}/%{name} -%{__mkdir} -p %{buildroot}%{_var}/log/jellyfin -%{__mkdir} -p %{buildroot}%{_var}/cache/jellyfin - -%{__install} -D -m 0644 %{SOURCE11} %{buildroot}%{_unitdir}/%{name}.service -%{__install} -D -m 0644 %{SOURCE12} %{buildroot}%{_sysconfdir}/sysconfig/%{name} -%{__install} -D -m 0600 %{SOURCE13} %{buildroot}%{_sysconfdir}/sudoers.d/%{name}-sudoers -%{__install} -D -m 0755 %{SOURCE14} %{buildroot}%{_libexecdir}/%{name}/restart.sh -%{__install} -D -m 0644 %{SOURCE16} %{buildroot}%{_prefix}/lib/firewalld/services/%{name}.xml - -%files -%{_libdir}/%{name}/jellyfin-web/* -%attr(755,root,root) %{_bindir}/%{name} -%{_libdir}/%{name}/*.json -%{_libdir}/%{name}/*.dll -%{_libdir}/%{name}/*.so -%{_libdir}/%{name}/*.a -%{_libdir}/%{name}/createdump -# Needs 755 else only root can run it since binary build by dotnet is 722 -%attr(755,root,root) %{_libdir}/%{name}/jellyfin -%{_libdir}/%{name}/SOS_README.md -%{_unitdir}/%{name}.service -%{_libexecdir}/%{name}/restart.sh -%{_prefix}/lib/firewalld/services/%{name}.xml -%attr(755,jellyfin,jellyfin) %dir %{_sysconfdir}/%{name} -%config %{_sysconfdir}/sysconfig/%{name} -%config(noreplace) %attr(600,root,root) %{_sysconfdir}/sudoers.d/%{name}-sudoers -%config(noreplace) %{_sysconfdir}/systemd/system/%{name}.service.d/override.conf -%config(noreplace) %attr(644,jellyfin,jellyfin) %{_sysconfdir}/%{name}/logging.json -%attr(750,jellyfin,jellyfin) %dir %{_sharedstatedir}/jellyfin -%attr(-,jellyfin,jellyfin) %dir %{_var}/log/jellyfin -%attr(750,jellyfin,jellyfin) %dir %{_var}/cache/jellyfin -%if 0%{?fedora} -%license LICENSE -%else -%{_datadir}/licenses/%{name}/LICENSE -%endif - -%pre -getent group jellyfin >/dev/null || groupadd -r jellyfin -getent passwd jellyfin >/dev/null || \ - useradd -r -g jellyfin -d %{_sharedstatedir}/jellyfin -s /sbin/nologin \ - -c "Jellyfin default user" jellyfin -exit 0 - -%post -# Move existing configuration cache and logs to their new locations and symlink them. -if [ $1 -gt 1 ] ; then - service_state=$(systemctl is-active jellyfin.service) - if [ "${service_state}" = "active" ]; then - systemctl stop jellyfin.service - fi - if [ ! -L %{_sharedstatedir}/%{name}/config ]; then - mv %{_sharedstatedir}/%{name}/config/* %{_sysconfdir}/%{name}/ - rmdir %{_sharedstatedir}/%{name}/config - ln -sf %{_sysconfdir}/%{name} %{_sharedstatedir}/%{name}/config - fi - if [ ! -L %{_sharedstatedir}/%{name}/logs ]; then - mv %{_sharedstatedir}/%{name}/logs/* %{_var}/log/jellyfin - rmdir %{_sharedstatedir}/%{name}/logs - ln -sf %{_var}/log/jellyfin %{_sharedstatedir}/%{name}/logs - fi - if [ ! -L %{_sharedstatedir}/%{name}/cache ]; then - mv %{_sharedstatedir}/%{name}/cache/* %{_var}/cache/jellyfin - rmdir %{_sharedstatedir}/%{name}/cache - ln -sf %{_var}/cache/jellyfin %{_sharedstatedir}/%{name}/cache - fi - if [ "${service_state}" = "active" ]; then - systemctl start jellyfin.service - fi -fi -%systemd_post jellyfin.service - -%preun -%systemd_preun jellyfin.service - -%postun -%systemd_postun_with_restart jellyfin.service - -%changelog -* Fri Oct 11 2019 Jellyfin Packaging Team -- New upstream version 10.5.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.5.0 -* Sat Aug 31 2019 Jellyfin Packaging Team -- New upstream version 10.4.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.4.0 -* Wed Jul 24 2019 Jellyfin Packaging Team -- New upstream version 10.3.7; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.7 -* Sat Jul 06 2019 Jellyfin Packaging Team -- New upstream version 10.3.6; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.6 -* Sun Jun 09 2019 Jellyfin Packaging Team -- New upstream version 10.3.5; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.5 -* Thu Jun 06 2019 Jellyfin Packaging Team -- New upstream version 10.3.4; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.4 -* Fri May 17 2019 Jellyfin Packaging Team -- New upstream version 10.3.3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.3 -* Tue Apr 30 2019 Jellyfin Packaging Team -- New upstream version 10.3.2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.2 -* Sat Apr 20 2019 Jellyfin Packaging Team -- New upstream version 10.3.1; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.1 -* Fri Apr 19 2019 Jellyfin Packaging Team -- New upstream version 10.3.0; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.3.0 diff --git a/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers b/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers deleted file mode 100644 index dd245af4b8..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/jellyfin.sudoers +++ /dev/null @@ -1,19 +0,0 @@ -# Allow jellyfin group to start, stop and restart itself -Cmnd_Alias RESTARTSERVER_SYSTEMD = /usr/bin/systemctl restart jellyfin, /bin/systemctl restart jellyfin -Cmnd_Alias STARTSERVER_SYSTEMD = /usr/bin/systemctl start jellyfin, /bin/systemctl start jellyfin -Cmnd_Alias STOPSERVER_SYSTEMD = /usr/bin/systemctl stop jellyfin, /bin/systemctl stop jellyfin - - -jellyfin ALL=(ALL) NOPASSWD: RESTARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STARTSERVER_SYSTEMD -jellyfin ALL=(ALL) NOPASSWD: STOPSERVER_SYSTEMD - -Defaults!RESTARTSERVER_SYSTEMD !requiretty -Defaults!STARTSERVER_SYSTEMD !requiretty -Defaults!STOPSERVER_SYSTEMD !requiretty - -# Allow the server to mount iso images -jellyfin ALL=(ALL) NOPASSWD: /bin/mount -jellyfin ALL=(ALL) NOPASSWD: /bin/umount - -Defaults:jellyfin !requiretty diff --git a/deployment/old/fedora-package-x64/pkg-src/restart.sh b/deployment/old/fedora-package-x64/pkg-src/restart.sh deleted file mode 100755 index 9b64b6d728..0000000000 --- a/deployment/old/fedora-package-x64/pkg-src/restart.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# restart.sh - Jellyfin server restart script -# Part of the Jellyfin project (https://github.com/jellyfin) -# -# This script restarts the Jellyfin daemon on Linux when using -# the Restart button on the admin dashboard. It supports the -# systemctl, service, and traditional /etc/init.d (sysv) restart -# methods, chosen automatically by which one is found first (in -# that order). -# -# This script is used by the Debian/Ubuntu/Fedora/CentOS packages. - -get_service_command() { - for command in systemctl service; do - if which $command &>/dev/null; then - echo $command && return - fi - done - echo "sysv" -} - -cmd="$( get_service_command )" -echo "Detected service control platform '$cmd'; using it to restart Jellyfin..." -case $cmd in - 'systemctl') - echo "sleep 2; /usr/bin/sudo $( which systemctl ) restart jellyfin" | at now - ;; - 'service') - echo "sleep 2; /usr/bin/sudo $( which service ) jellyfin restart" | at now - ;; - 'sysv') - echo "sleep 2; /usr/bin/sudo /etc/init.d/jellyfin restart" | at now - ;; -esac -exit 0 diff --git a/deployment/old/linux-x64/Dockerfile b/deployment/old/linux-x64/Dockerfile deleted file mode 100644 index c47057546d..0000000000 --- a/deployment/old/linux-x64/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/linux-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/linux-x64/clean.sh b/deployment/old/linux-x64/clean.sh deleted file mode 100755 index c07501a7bb..0000000000 --- a/deployment/old/linux-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/linux-x64/dependencies.txt b/deployment/old/linux-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/linux-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/linux-x64/docker-build.sh b/deployment/old/linux-x64/docker-build.sh deleted file mode 100755 index e33328a36a..0000000000 --- a/deployment/old/linux-x64/docker-build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Builds the TAR archive inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build archives -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime linux-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" -tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/linux-x64/package.sh b/deployment/old/linux-x64/package.sh deleted file mode 100755 index dfe8a9aa4a..0000000000 --- a/deployment/old/linux-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/macos/Dockerfile b/deployment/old/macos/Dockerfile deleted file mode 100644 index b522df8848..0000000000 --- a/deployment/old/macos/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/macos -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/macos/clean.sh b/deployment/old/macos/clean.sh deleted file mode 100755 index c07501a7bb..0000000000 --- a/deployment/old/macos/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/macos/dependencies.txt b/deployment/old/macos/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/macos/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/macos/docker-build.sh b/deployment/old/macos/docker-build.sh deleted file mode 100755 index f9417388d7..0000000000 --- a/deployment/old/macos/docker-build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Builds the TAR archive inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build archives -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime osx-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" -tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/macos/package.sh b/deployment/old/macos/package.sh deleted file mode 100755 index 464c0d382f..0000000000 --- a/deployment/old/macos/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-macos-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/portable/Dockerfile b/deployment/old/portable/Dockerfile deleted file mode 100644 index 965eb82b86..0000000000 --- a/deployment/old/portable/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/portable -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/portable/clean.sh b/deployment/old/portable/clean.sh deleted file mode 100755 index c07501a7bb..0000000000 --- a/deployment/old/portable/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-linux-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/portable/dependencies.txt b/deployment/old/portable/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/portable/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/portable/docker-build.sh b/deployment/old/portable/docker-build.sh deleted file mode 100755 index 094190bbf6..0000000000 --- a/deployment/old/portable/docker-build.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -# Builds the TAR archive inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build archives -dotnet publish Jellyfin.Server --configuration Release --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none" -tar -cvzf /jellyfin_${version}.portable.tar.gz -C /dist jellyfin_${version} -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.tar.gz ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/portable/package.sh b/deployment/old/portable/package.sh deleted file mode 100755 index 0ceb54dda1..0000000000 --- a/deployment/old/portable/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-portable-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 b/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 deleted file mode 100644 index b11994a18a..0000000000 --- a/deployment/old/ubuntu-package-arm64/Dockerfile.amd64 +++ /dev/null @@ -1,59 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Prepare the cross-toolchain -RUN rm /etc/apt/sources.list \ - && export CODENAME="$( lsb_release -c -s )" \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && echo "deb [arch=arm64] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/arm64.list \ - && dpkg --add-architecture arm64 \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="arm64" cross-gcc-gensource 6 \ - && cd cross-gcc-packages-amd64/cross-gcc-6-arm64 \ - && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ - && apt-get install -y gcc-6-source libstdc++6-arm64-cross binutils-aarch64-linux-gnu bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:arm64 linux-libc-dev:arm64 libgcc1:arm64 libcurl4-openssl-dev:arm64 libfontconfig1-dev:arm64 libfreetype6-dev:arm64 liblttng-ust0:arm64 libstdc++6:arm64 libssl-dev:arm64 - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 b/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 deleted file mode 100644 index 8f004b2f1a..0000000000 --- a/deployment/old/ubuntu-package-arm64/Dockerfile.arm64 +++ /dev/null @@ -1,40 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-arm64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=arm64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev liblttng-ust0 libssl-dev - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/5a4c8f96-1c73-401c-a6de-8e100403188a/0ce6ab39747e2508366d498f9c0a0669/dotnet-sdk-3.1.100-linux-arm64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-arm64/clean.sh b/deployment/old/ubuntu-package-arm64/clean.sh deleted file mode 100755 index 82d427f9e5..0000000000 --- a/deployment/old/ubuntu-package-arm64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/ubuntu-package-arm64/dependencies.txt b/deployment/old/ubuntu-package-arm64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/ubuntu-package-arm64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/ubuntu-package-arm64/docker-build.sh b/deployment/old/ubuntu-package-arm64/docker-build.sh deleted file mode 100755 index 67ab6bd74b..0000000000 --- a/deployment/old/ubuntu-package-arm64/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarm64 - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-arm64/package.sh b/deployment/old/ubuntu-package-arm64/package.sh deleted file mode 100755 index d1140a7274..0000000000 --- a/deployment/old/ubuntu-package-arm64/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu_arm64-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.arm64" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-arm64/pkg-src b/deployment/old/ubuntu-package-arm64/pkg-src deleted file mode 120000 index 4c695fea17..0000000000 --- a/deployment/old/ubuntu-package-arm64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 b/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 deleted file mode 100644 index e475b14389..0000000000 --- a/deployment/old/ubuntu-package-armhf/Dockerfile.amd64 +++ /dev/null @@ -1,59 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Prepare the cross-toolchain -RUN rm /etc/apt/sources.list \ - && export CODENAME="$( lsb_release -c -s )" \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/amd64.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME} main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-updates main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-backports main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && echo "deb [arch=armhf] http://ports.ubuntu.com/ ${CODENAME}-security main restricted universe multiverse" >>/etc/apt/sources.list.d/armhf.list \ - && dpkg --add-architecture armhf \ - && apt-get update \ - && apt-get install -y cross-gcc-dev \ - && TARGET_LIST="armhf" cross-gcc-gensource 6 \ - && cd cross-gcc-packages-amd64/cross-gcc-6-armhf \ - && ln -fs /usr/share/zoneinfo/America/Toronto /etc/localtime \ - && apt-get install -y gcc-6-source libstdc++6-armhf-cross binutils-arm-linux-gnueabihf bison flex libtool gdb sharutils netbase libcloog-isl-dev libmpc-dev libmpfr-dev libgmp-dev systemtap-sdt-dev autogen expect chrpath zlib1g-dev zip libc6-dev:armhf linux-libc-dev:armhf libgcc1:armhf libcurl4-openssl-dev:armhf libfontconfig1-dev:armhf libfreetype6-dev:armhf liblttng-ust0:armhf libstdc++6:armhf libssl-dev:armhf - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-armhf/Dockerfile.armhf b/deployment/old/ubuntu-package-armhf/Dockerfile.armhf deleted file mode 100644 index 0e71fa6938..0000000000 --- a/deployment/old/ubuntu-package-armhf/Dockerfile.armhf +++ /dev/null @@ -1,40 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-armhf -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=armhf - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev liblttng-ust0 libssl-dev - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/67766a96-eb8c-4cd2-bca4-ea63d2cc115c/7bf13840aa2ed88793b7315d5e0d74e6/dotnet-sdk-3.1.100-linux-arm.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -# Link to Debian source dir; mkdir needed or it fails, can't force dest -RUN mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-armhf/clean.sh b/deployment/old/ubuntu-package-armhf/clean.sh deleted file mode 100755 index 82d427f9e5..0000000000 --- a/deployment/old/ubuntu-package-armhf/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/ubuntu-package-armhf/dependencies.txt b/deployment/old/ubuntu-package-armhf/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/ubuntu-package-armhf/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/ubuntu-package-armhf/docker-build.sh b/deployment/old/ubuntu-package-armhf/docker-build.sh deleted file mode 100755 index 1bd7fb2911..0000000000 --- a/deployment/old/ubuntu-package-armhf/docker-build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -export CONFIG_SITE=/etc/dpkg-cross/cross-config.${ARCH} -dpkg-buildpackage -us -uc -aarmhf - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-armhf/package.sh b/deployment/old/ubuntu-package-armhf/package.sh deleted file mode 100755 index 2ceb3e8165..0000000000 --- a/deployment/old/ubuntu-package-armhf/package.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -ARCH="$( arch )" -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu_armhf-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Determine which Dockerfile to use -case $ARCH in - 'x86_64') - DOCKERFILE="Dockerfile.amd64" - ;; - 'armv7l') - DOCKERFILE="Dockerfile.armhf" - ;; -esac - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./${DOCKERFILE} -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-armhf/pkg-src b/deployment/old/ubuntu-package-armhf/pkg-src deleted file mode 120000 index 4c695fea17..0000000000 --- a/deployment/old/ubuntu-package-armhf/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src \ No newline at end of file diff --git a/deployment/old/ubuntu-package-x64/Dockerfile b/deployment/old/ubuntu-package-x64/Dockerfile deleted file mode 100644 index e2dda6392c..0000000000 --- a/deployment/old/ubuntu-package-x64/Dockerfile +++ /dev/null @@ -1,36 +0,0 @@ -FROM ubuntu:bionic -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/ubuntu-package-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Ubuntu build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev liblttng-ust0 \ - && ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh \ - && mkdir -p ${SOURCE_DIR} && ln -sf ${PLATFORM_DIR}/pkg-src ${SOURCE_DIR}/debian - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install npm package manager -RUN wget -q -O- https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \ - && echo "deb https://deb.nodesource.com/node_10.x $(lsb_release -s -c) main" > /etc/apt/sources.list.d/npm.list \ - && apt update \ - && apt install -y nodejs - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/ubuntu-package-x64/clean.sh b/deployment/old/ubuntu-package-x64/clean.sh deleted file mode 100755 index 82d427f9e5..0000000000 --- a/deployment/old/ubuntu-package-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/ubuntu-package-x64/dependencies.txt b/deployment/old/ubuntu-package-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/ubuntu-package-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/ubuntu-package-x64/docker-build.sh b/deployment/old/ubuntu-package-x64/docker-build.sh deleted file mode 100755 index 962a522ebc..0000000000 --- a/deployment/old/ubuntu-package-x64/docker-build.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Builds the DEB inside the Docker container - -set -o errexit -set -o xtrace - -# Move to source directory -pushd ${SOURCE_DIR} - -# Remove build-dep for dotnet-sdk-3.1, since it's not a package in this image -sed -i '/dotnet-sdk-3.1,/d' debian/control - -# Build DEB -dpkg-buildpackage -us -uc - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/deb -mv /jellyfin[-_]* ${ARTIFACT_DIR}/deb/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/ubuntu-package-x64/package.sh b/deployment/old/ubuntu-package-x64/package.sh deleted file mode 100755 index 08c003778b..0000000000 --- a/deployment/old/ubuntu-package-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-ubuntu-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/deb/* "${output_dir}" diff --git a/deployment/old/ubuntu-package-x64/pkg-src b/deployment/old/ubuntu-package-x64/pkg-src deleted file mode 120000 index 0bb6d55249..0000000000 --- a/deployment/old/ubuntu-package-x64/pkg-src +++ /dev/null @@ -1 +0,0 @@ -../debian-package-x64/pkg-src/ \ No newline at end of file diff --git a/deployment/old/unraid/docker-templates/README.md b/deployment/old/unraid/docker-templates/README.md deleted file mode 100644 index 2c268e8b3e..0000000000 --- a/deployment/old/unraid/docker-templates/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# docker-templates - -### Installation: - -Open unRaid GUI (at least unRaid 6.5) - -Click on the Docker tab - -Add the following line under "Template Repositories" - -https://github.com/jellyfin/jellyfin/blob/master/deployment/unraid/docker-templates - -Click save than click on Add Container and select jellyfin. - -Adjust to your paths to your liking and off you go! diff --git a/deployment/old/unraid/docker-templates/jellyfin.xml b/deployment/old/unraid/docker-templates/jellyfin.xml deleted file mode 100644 index 57b4cc5ae1..0000000000 --- a/deployment/old/unraid/docker-templates/jellyfin.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - https://raw.githubusercontent.com/jellyfin/jellyfin/deployment/unraid/docker-templates/jellyfin.xml - False - MediaApp:Video MediaApp:Music MediaApp:Photos MediaServer:Video MediaServer:Music MediaServer:Photos - Jellyfin - - Jellyfin is The Free Software Media Browser Converted By Community Applications Always verify this template (and values) against the dockerhub support page for the container!![br][br] - You can add as many mount points as needed for recordings, movies ,etc. [br][br] - [b][span style='color: #E80000;']Directions:[/span][/b][br] - [b]/config[/b] : This is where Jellyfin will store it's databases and configuration.[br][br] - [b]Port[/b] : This is the default port for Jellyfin. (Will add ssl port later)[br][br] - [b]Media[/b] : This is the mounting point of your media. When you access it in Jellyfin it will be /media or whatever you chose for a mount point[br][br] - [b]Cache[/b] : This is where Jellyfin will store and manage cached files like images to serve to clients. This is not where all images are stored.[br][br] - [b]Tip:[/b] You can add more volume mappings if you wish Jellyfin has access to it. - - - Jellyfin Server is a home media server built on top of other popular open source technologies such as Service Stack, jQuery, jQuery mobile, and Mono and will remain completely free! - - https://www.reddit.com/r/jellyfin/ - https://hub.docker.com/r/jellyfin/jellyfin/ - https://github.com/jellyfin/jellyfin/> - jellyfin/jellyfin - https://jellyfin.media/ - true - false - - host - - - 8096 - 8096 - tcp - - - - - - /mnt/user/appdata/Jellyfin - /config - rw - - - /mnt/user - /media - rw - - - /mnt/user/appdata/Jellyfin/cache/ - /cache - rw - - - http://[IP]:[PORT:8096]/ - https://raw.githubusercontent.com/binhex/docker-templates/master/binhex/images/jellyfin-icon.png - - diff --git a/deployment/old/win-x64/Dockerfile b/deployment/old/win-x64/Dockerfile deleted file mode 100644 index 8a33749541..0000000000 --- a/deployment/old/win-x64/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/win-x64 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/win-x64/clean.sh b/deployment/old/win-x64/clean.sh deleted file mode 100755 index 6c183f3371..0000000000 --- a/deployment/old/win-x64/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x64-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/win-x64/dependencies.txt b/deployment/old/win-x64/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/win-x64/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/win-x64/docker-build.sh b/deployment/old/win-x64/docker-build.sh deleted file mode 100755 index 79e5fb0bcd..0000000000 --- a/deployment/old/win-x64/docker-build.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Builds the ZIP archive inside the Docker container - -set -o errexit -set -o xtrace - -# Version variables -NSSM_VERSION="nssm-2.24-101-g897c7ad" -NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" -FFMPEG_VERSION="ffmpeg-4.2.1-win64-static" -FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win64/static/${FFMPEG_VERSION}.zip" - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build binary -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x64 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" - -# Prepare addins -addin_build_dir="$( mktemp -d )" -wget ${NSSM_URL} -O ${addin_build_dir}/nssm.zip -wget ${FFMPEG_URL} -O ${addin_build_dir}/ffmpeg.zip -unzip ${addin_build_dir}/nssm.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${NSSM_VERSION}/win64/nssm.exe /dist/jellyfin_${version}/nssm.exe -unzip ${addin_build_dir}/ffmpeg.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffmpeg.exe /dist/jellyfin_${version}/ffmpeg.exe -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffprobe.exe /dist/jellyfin_${version}/ffprobe.exe -rm -rf ${addin_build_dir} - -# Prepare scripts -cp ${SOURCE_DIR}/deployment/windows/legacy/install-jellyfin.ps1 /dist/jellyfin_${version}/install-jellyfin.ps1 -cp ${SOURCE_DIR}/deployment/windows/legacy/install.bat /dist/jellyfin_${version}/install.bat - -# Create zip package -pushd /dist -zip -r /jellyfin_${version}.portable.zip jellyfin_${version} -popd -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.zip ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/win-x64/package.sh b/deployment/old/win-x64/package.sh deleted file mode 100755 index a8ab190fa5..0000000000 --- a/deployment/old/win-x64/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x64-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" diff --git a/deployment/old/win-x86/Dockerfile b/deployment/old/win-x86/Dockerfile deleted file mode 100644 index f8dc5be83d..0000000000 --- a/deployment/old/win-x86/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM debian:10 -# Docker build arguments -ARG SOURCE_DIR=/jellyfin -ARG PLATFORM_DIR=/jellyfin/deployment/win-x86 -ARG ARTIFACT_DIR=/dist -ARG SDK_VERSION=3.1 -# Docker run environment -ENV SOURCE_DIR=/jellyfin -ENV ARTIFACT_DIR=/dist -ENV DEB_BUILD_OPTIONS=noddebs -ENV ARCH=amd64 - -# Prepare Debian build environment -RUN apt-get update \ - && apt-get install -y apt-transport-https debhelper gnupg wget devscripts mmv libc6-dev libcurl4-openssl-dev libfontconfig1-dev libfreetype6-dev libssl-dev libssl1.1 liblttng-ust0 zip - -# Install dotnet repository -# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current -RUN wget https://download.visualstudio.microsoft.com/download/pr/d731f991-8e68-4c7c-8ea0-fad5605b077a/49497b5420eecbd905158d86d738af64/dotnet-sdk-3.1.100-linux-x64.tar.gz -O dotnet-sdk.tar.gz \ - && mkdir -p dotnet-sdk \ - && tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \ - && ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet - -# Install yarn package manager -RUN wget -q -O- https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ - && echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list \ - && apt update \ - && apt install -y yarn - -# Link to docker-build script -RUN ln -sf ${PLATFORM_DIR}/docker-build.sh /docker-build.sh - -VOLUME ${ARTIFACT_DIR}/ - -COPY . ${SOURCE_DIR}/ - -ENTRYPOINT ["/docker-build.sh"] diff --git a/deployment/old/win-x86/clean.sh b/deployment/old/win-x86/clean.sh deleted file mode 100755 index 8b78c5e4b6..0000000000 --- a/deployment/old/win-x86/clean.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -keep_artifacts="${1}" - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x86-build" - -rm -rf "${package_temporary_dir}" &>/dev/null \ - || sudo rm -rf "${package_temporary_dir}" &>/dev/null - -rm -rf "${output_dir}" &>/dev/null \ - || sudo rm -rf "${output_dir}" &>/dev/null - -if [[ ${keep_artifacts} == 'n' ]]; then - docker_sudo="" - if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo=sudo - fi - ${docker_sudo} docker image rm ${image_name} --force -fi diff --git a/deployment/old/win-x86/dependencies.txt b/deployment/old/win-x86/dependencies.txt deleted file mode 100644 index bdb9670965..0000000000 --- a/deployment/old/win-x86/dependencies.txt +++ /dev/null @@ -1 +0,0 @@ -docker diff --git a/deployment/old/win-x86/docker-build.sh b/deployment/old/win-x86/docker-build.sh deleted file mode 100755 index 977dcf78fa..0000000000 --- a/deployment/old/win-x86/docker-build.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash - -# Builds the ZIP archive inside the Docker container - -set -o errexit -set -o xtrace - -# Version variables -NSSM_VERSION="nssm-2.24-101-g897c7ad" -NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" -FFMPEG_VERSION="ffmpeg-4.2.1-win32-static" -FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win32/static/${FFMPEG_VERSION}.zip" - -# Move to source directory -pushd ${SOURCE_DIR} - -# Clone down and build Web frontend -web_build_dir="$( mktemp -d )" -web_target="${SOURCE_DIR}/MediaBrowser.WebDashboard/jellyfin-web" -git clone https://github.com/jellyfin/jellyfin-web.git ${web_build_dir}/ -pushd ${web_build_dir} -if [[ -n ${web_branch} ]]; then - checkout -b origin/${web_branch} -fi -yarn install -mkdir -p ${web_target} -mv dist/* ${web_target}/ -popd -rm -rf ${web_build_dir} - -# Get version -version="$( grep "version:" ./build.yaml | sed -E 's/version: "([0-9\.]+.*)"/\1/' )" - -# Build binary -dotnet publish Jellyfin.Server --configuration Release --self-contained --runtime win-x86 --output /dist/jellyfin_${version}/ "-p:GenerateDocumentationFile=false;DebugSymbols=false;DebugType=none;UseAppHost=true" - -# Prepare addins -addin_build_dir="$( mktemp -d )" -wget ${NSSM_URL} -O ${addin_build_dir}/nssm.zip -wget ${FFMPEG_URL} -O ${addin_build_dir}/ffmpeg.zip -unzip ${addin_build_dir}/nssm.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${NSSM_VERSION}/win64/nssm.exe /dist/jellyfin_${version}/nssm.exe -unzip ${addin_build_dir}/ffmpeg.zip -d ${addin_build_dir} -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffmpeg.exe /dist/jellyfin_${version}/ffmpeg.exe -cp ${addin_build_dir}/${FFMPEG_VERSION}/bin/ffprobe.exe /dist/jellyfin_${version}/ffprobe.exe -rm -rf ${addin_build_dir} - -# Prepare scripts -cp ${SOURCE_DIR}/deployment/windows/legacy/install-jellyfin.ps1 /dist/jellyfin_${version}/install-jellyfin.ps1 -cp ${SOURCE_DIR}/deployment/windows/legacy/install.bat /dist/jellyfin_${version}/install.bat - -# Create zip package -pushd /dist -zip -r /jellyfin_${version}.portable.zip jellyfin_${version} -popd -rm -rf /dist/jellyfin_${version} - -# Move the artifacts out -mkdir -p ${ARTIFACT_DIR}/ -mv /jellyfin[-_]*.zip ${ARTIFACT_DIR}/ -chown -Rc $(stat -c %u:%g ${ARTIFACT_DIR}) ${ARTIFACT_DIR} diff --git a/deployment/old/win-x86/package.sh b/deployment/old/win-x86/package.sh deleted file mode 100755 index 65e7e2928c..0000000000 --- a/deployment/old/win-x86/package.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash - -args="${@}" -declare -a docker_envvars -for arg in ${args}; do - docker_envvars+=("-e ${arg}") -done - -WORKDIR="$( pwd )" - -package_temporary_dir="${WORKDIR}/pkg-dist-tmp" -output_dir="${WORKDIR}/pkg-dist" -current_user="$( whoami )" -image_name="jellyfin-windows-x86-build" - -# Determine if sudo should be used for Docker -if [[ ! -z $(id -Gn | grep -q 'docker') ]] \ - && [[ ! ${EUID:-1000} -eq 0 ]] \ - && [[ ! ${USER} == "root" ]] \ - && [[ ! -z $( echo "${OSTYPE}" | grep -q "darwin" ) ]]; then - docker_sudo="sudo" -else - docker_sudo="" -fi - -# Prepare temporary package dir -mkdir -p "${package_temporary_dir}" -# Set up the build environment Docker image -${docker_sudo} docker build ../.. -t "${image_name}" -f ./Dockerfile -# Build the DEBs and copy out to ${package_temporary_dir} -${docker_sudo} docker run --rm -v "${package_temporary_dir}:/dist" "${image_name}" ${docker_envvars} -# Move the DEBs to the output directory -mkdir -p "${output_dir}" -mv "${package_temporary_dir}"/* "${output_dir}" From 762a46045ee784c500f7fe4c2c0131ca83e8b50e Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:55:14 -0400 Subject: [PATCH 115/517] Update gitignore paths for debian/ --- .gitignore | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 17cf4a6277..f3ad8c09bd 100644 --- a/.gitignore +++ b/.gitignore @@ -244,14 +244,14 @@ pip-log.txt ######################### # Artifacts for debian-x64 -deployment/debian-package-x64/pkg-src/.debhelper/ -deployment/debian-package-x64/pkg-src/*.debhelper -deployment/debian-package-x64/pkg-src/debhelper-build-stamp -deployment/debian-package-x64/pkg-src/files -deployment/debian-package-x64/pkg-src/jellyfin.substvars -deployment/debian-package-x64/pkg-src/jellyfin/ +debian/.debhelper/ +debian/*.debhelper +debian/debhelper-build-stamp +debian/files +debian/jellyfin.substvars +debian/jellyfin/ # Don't ignore the debian/bin folder -!deployment/debian-package-x64/pkg-src/bin/ +!debian/bin/ deployment/**/dist/ deployment/**/pkg-dist/ From 7eac3684862380a857edc6c7e98c20f25c5b9a03 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Thu, 9 Apr 2020 11:55:27 -0400 Subject: [PATCH 116/517] Fix missing restart script --- debian/bin/restart.sh | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100755 debian/bin/restart.sh diff --git a/debian/bin/restart.sh b/debian/bin/restart.sh new file mode 100755 index 0000000000..9b64b6d728 --- /dev/null +++ b/debian/bin/restart.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# restart.sh - Jellyfin server restart script +# Part of the Jellyfin project (https://github.com/jellyfin) +# +# This script restarts the Jellyfin daemon on Linux when using +# the Restart button on the admin dashboard. It supports the +# systemctl, service, and traditional /etc/init.d (sysv) restart +# methods, chosen automatically by which one is found first (in +# that order). +# +# This script is used by the Debian/Ubuntu/Fedora/CentOS packages. + +get_service_command() { + for command in systemctl service; do + if which $command &>/dev/null; then + echo $command && return + fi + done + echo "sysv" +} + +cmd="$( get_service_command )" +echo "Detected service control platform '$cmd'; using it to restart Jellyfin..." +case $cmd in + 'systemctl') + echo "sleep 2; /usr/bin/sudo $( which systemctl ) restart jellyfin" | at now + ;; + 'service') + echo "sleep 2; /usr/bin/sudo $( which service ) jellyfin restart" | at now + ;; + 'sysv') + echo "sleep 2; /usr/bin/sudo /etc/init.d/jellyfin restart" | at now + ;; +esac +exit 0 From 4d949cb38b531455bc42551a7c095a0c2a00170e Mon Sep 17 00:00:00 2001 From: hauntingEcho <1661988+hauntingEcho@users.noreply.github.com> Date: Tue, 31 Mar 2020 21:41:10 -0500 Subject: [PATCH 117/517] Specify a version for jellyfin-ffmpeg dependency in .deb Lower versions cause #2126 in Jellyfin >= 10.4.3 --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 5559700cf5..896d8286b7 100644 --- a/debian/control +++ b/debian/control @@ -21,7 +21,7 @@ Conflicts: mediabrowser, emby, emby-server-beta, jellyfin-dev, emby-server Architecture: any Depends: at, libsqlite3-0, - jellyfin-ffmpeg, + jellyfin-ffmpeg (>= 4.2.1-2), libfontconfig1, libfreetype6, libssl1.1 From 4e894b4b660f33e8c8a6ce9b235edaaf313b9c9e Mon Sep 17 00:00:00 2001 From: ferferga Date: Thu, 9 Apr 2020 18:23:21 +0200 Subject: [PATCH 118/517] Remove unnecessary space in hardware decoders argument for ffmpeg --- .../MediaEncoding/EncodingHelper.cs | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 95b7df9bd6..3fb8c825a6 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2549,7 +2549,7 @@ namespace MediaBrowser.Controller.MediaEncoding encodingOptions.HardwareDecodingCodecs = Array.Empty(); return null; } - return "-c:v h264_qsv "; + return "-c:v h264_qsv"; } break; case "hevc": @@ -2557,19 +2557,19 @@ namespace MediaBrowser.Controller.MediaEncoding if (_mediaEncoder.SupportsDecoder("hevc_qsv") && encodingOptions.HardwareDecodingCodecs.Contains("hevc", StringComparer.OrdinalIgnoreCase)) { //return "-c:v hevc_qsv -load_plugin hevc_hw "; - return "-c:v hevc_qsv "; + return "-c:v hevc_qsv"; } break; case "mpeg2video": if (_mediaEncoder.SupportsDecoder("mpeg2_qsv") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg2video", StringComparer.OrdinalIgnoreCase)) { - return "-c:v mpeg2_qsv "; + return "-c:v mpeg2_qsv"; } break; case "vc1": if (_mediaEncoder.SupportsDecoder("vc1_qsv") && encodingOptions.HardwareDecodingCodecs.Contains("vc1", StringComparer.OrdinalIgnoreCase)) { - return "-c:v vc1_qsv "; + return "-c:v vc1_qsv"; } break; } @@ -2589,32 +2589,32 @@ namespace MediaBrowser.Controller.MediaEncoding encodingOptions.HardwareDecodingCodecs = Array.Empty(); return null; } - return "-c:v h264_cuvid "; + return "-c:v h264_cuvid"; } break; case "hevc": case "h265": if (_mediaEncoder.SupportsDecoder("hevc_cuvid") && encodingOptions.HardwareDecodingCodecs.Contains("hevc", StringComparer.OrdinalIgnoreCase)) { - return "-c:v hevc_cuvid "; + return "-c:v hevc_cuvid"; } break; case "mpeg2video": if (_mediaEncoder.SupportsDecoder("mpeg2_cuvid") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg2video", StringComparer.OrdinalIgnoreCase)) { - return "-c:v mpeg2_cuvid "; + return "-c:v mpeg2_cuvid"; } break; case "vc1": if (_mediaEncoder.SupportsDecoder("vc1_cuvid") && encodingOptions.HardwareDecodingCodecs.Contains("vc1", StringComparer.OrdinalIgnoreCase)) { - return "-c:v vc1_cuvid "; + return "-c:v vc1_cuvid"; } break; case "mpeg4": if (_mediaEncoder.SupportsDecoder("mpeg4_cuvid") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg4", StringComparer.OrdinalIgnoreCase)) { - return "-c:v mpeg4_cuvid "; + return "-c:v mpeg4_cuvid"; } break; } @@ -2628,38 +2628,38 @@ namespace MediaBrowser.Controller.MediaEncoding case "h264": if (_mediaEncoder.SupportsDecoder("h264_mediacodec") && encodingOptions.HardwareDecodingCodecs.Contains("h264", StringComparer.OrdinalIgnoreCase)) { - return "-c:v h264_mediacodec "; + return "-c:v h264_mediacodec"; } break; case "hevc": case "h265": if (_mediaEncoder.SupportsDecoder("hevc_mediacodec") && encodingOptions.HardwareDecodingCodecs.Contains("hevc", StringComparer.OrdinalIgnoreCase)) { - return "-c:v hevc_mediacodec "; + return "-c:v hevc_mediacodec"; } break; case "mpeg2video": if (_mediaEncoder.SupportsDecoder("mpeg2_mediacodec") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg2video", StringComparer.OrdinalIgnoreCase)) { - return "-c:v mpeg2_mediacodec "; + return "-c:v mpeg2_mediacodec"; } break; case "mpeg4": if (_mediaEncoder.SupportsDecoder("mpeg4_mediacodec") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg4", StringComparer.OrdinalIgnoreCase)) { - return "-c:v mpeg4_mediacodec "; + return "-c:v mpeg4_mediacodec"; } break; case "vp8": if (_mediaEncoder.SupportsDecoder("vp8_mediacodec") && encodingOptions.HardwareDecodingCodecs.Contains("vp8", StringComparer.OrdinalIgnoreCase)) { - return "-c:v vp8_mediacodec "; + return "-c:v vp8_mediacodec"; } break; case "vp9": if (_mediaEncoder.SupportsDecoder("vp9_mediacodec") && encodingOptions.HardwareDecodingCodecs.Contains("vp9", StringComparer.OrdinalIgnoreCase)) { - return "-c:v vp9_mediacodec "; + return "-c:v vp9_mediacodec"; } break; } @@ -2673,25 +2673,25 @@ namespace MediaBrowser.Controller.MediaEncoding case "h264": if (_mediaEncoder.SupportsDecoder("h264_mmal") && encodingOptions.HardwareDecodingCodecs.Contains("h264", StringComparer.OrdinalIgnoreCase)) { - return "-c:v h264_mmal "; + return "-c:v h264_mmal"; } break; case "mpeg2video": if (_mediaEncoder.SupportsDecoder("mpeg2_mmal") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg2video", StringComparer.OrdinalIgnoreCase)) { - return "-c:v mpeg2_mmal "; + return "-c:v mpeg2_mmal"; } break; case "mpeg4": if (_mediaEncoder.SupportsDecoder("mpeg4_mmal") && encodingOptions.HardwareDecodingCodecs.Contains("mpeg4", StringComparer.OrdinalIgnoreCase)) { - return "-c:v mpeg4_mmal "; + return "-c:v mpeg4_mmal"; } break; case "vc1": if (_mediaEncoder.SupportsDecoder("vc1_mmal") && encodingOptions.HardwareDecodingCodecs.Contains("vc1", StringComparer.OrdinalIgnoreCase)) { - return "-c:v vc1_mmal "; + return "-c:v vc1_mmal"; } break; } From 9cca964b0880dc41792fe27ee03e69609ff2ac7e Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Thu, 9 Apr 2020 19:22:29 +0200 Subject: [PATCH 119/517] Address comments --- .../MediaInfo/LiveStreamRequest.cs | 32 +++++++++---------- .../Providers/ImageProviderInfo.cs | 12 +++---- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs index ea5d4e7d77..cce508809b 100644 --- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs +++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs @@ -15,23 +15,6 @@ namespace MediaBrowser.Model.MediaInfo DirectPlayProtocols = new MediaProtocol[] { MediaProtocol.Http }; } - public string OpenToken { get; set; } - public Guid UserId { get; set; } - public string PlaySessionId { get; set; } - public long? MaxStreamingBitrate { get; set; } - public long? StartTimeTicks { get; set; } - public int? AudioStreamIndex { get; set; } - public int? SubtitleStreamIndex { get; set; } - public int? MaxAudioChannels { get; set; } - public Guid ItemId { get; set; } - public DeviceProfile DeviceProfile { get; set; } - - public bool EnableDirectPlay { get; set; } - public bool EnableDirectStream { get; set; } - public MediaProtocol[] DirectPlayProtocols { get; set; } - - - public LiveStreamRequest(AudioOptions options) { MaxStreamingBitrate = options.MaxBitrate; @@ -47,5 +30,20 @@ namespace MediaBrowser.Model.MediaInfo SubtitleStreamIndex = videoOptions.SubtitleStreamIndex; } } + + public string OpenToken { get; set; } + public Guid UserId { get; set; } + public string PlaySessionId { get; set; } + public long? MaxStreamingBitrate { get; set; } + public long? StartTimeTicks { get; set; } + public int? AudioStreamIndex { get; set; } + public int? SubtitleStreamIndex { get; set; } + public int? MaxAudioChannels { get; set; } + public Guid ItemId { get; set; } + public DeviceProfile DeviceProfile { get; set; } + + public bool EnableDirectPlay { get; set; } + public bool EnableDirectStream { get; set; } + public MediaProtocol[] DirectPlayProtocols { get; set; } } } diff --git a/MediaBrowser.Model/Providers/ImageProviderInfo.cs b/MediaBrowser.Model/Providers/ImageProviderInfo.cs index c63a2ceda8..d1a7c25069 100644 --- a/MediaBrowser.Model/Providers/ImageProviderInfo.cs +++ b/MediaBrowser.Model/Providers/ImageProviderInfo.cs @@ -1,6 +1,3 @@ -#pragma warning disable CS1591 - -using System; using MediaBrowser.Model.Entities; namespace MediaBrowser.Model.Providers @@ -17,11 +14,14 @@ namespace MediaBrowser.Model.Providers } /// - /// Gets or sets the name. + /// Gets the name. /// /// The name. - public string Name { get; set; } + public string Name { get; } - public ImageType[] SupportedImages { get; set; } + /// + /// Gets the supported image types. + /// + public ImageType[] SupportedImages { get; } } } From 17e8813378c2fe1a83d1eddb829dae68f8c71bfe Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 11 Apr 2020 10:53:13 -0400 Subject: [PATCH 120/517] Use ActivatorUtilities to construct MediaEncoder and update constructor to inject EncodingHelper correctly --- Emby.Server.Implementations/ApplicationHost.cs | 16 ++++------------ .../Encoder/MediaEncoder.cs | 16 ++++------------ 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 5b93981f01..ad0a69b19e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -88,7 +88,6 @@ using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dlna; -using MediaBrowser.Model.Events; using MediaBrowser.Model.Globalization; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; @@ -106,7 +105,6 @@ using MediaBrowser.WebDashboard.Api; using MediaBrowser.XbmcMetadata.Providers; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using OperatingSystem = MediaBrowser.Common.System.OperatingSystem; @@ -614,17 +612,11 @@ namespace Emby.Server.Implementations serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); serviceCollection.AddSingleton(); - // TODO: Add StartupOptions.FFmpegPath to IConfiguration so this doesn't need to be constructed manually + // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required + // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation + serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); serviceCollection.AddSingleton(provider => - new MediaBrowser.MediaEncoding.Encoder.MediaEncoder( - provider.GetRequiredService>(), - provider.GetRequiredService(), - provider.GetRequiredService(), - provider.GetRequiredService(), - provider.GetRequiredService(), - provider.GetRequiredService, - provider.GetRequiredService(), - _startupOptions.FFmpegPath)); + ActivatorUtilities.CreateInstance(provider, _startupOptions.FFmpegPath ?? string.Empty)); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index f3f2b86eee..c5bba87802 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -40,8 +40,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly IFileSystem _fileSystem; private readonly IProcessFactory _processFactory; private readonly ILocalizationManager _localization; - private readonly Func _subtitleEncoder; - private readonly IConfiguration _configuration; + private readonly Lazy _encodingHelperFactory; private readonly string _startupOptionFFmpegPath; private readonly SemaphoreSlim _thumbnailResourcePool = new SemaphoreSlim(2, 2); @@ -49,8 +48,6 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly object _runningProcessesLock = new object(); private readonly List _runningProcesses = new List(); - private EncodingHelper _encodingHelper; - private string _ffmpegPath; private string _ffprobePath; @@ -60,8 +57,7 @@ namespace MediaBrowser.MediaEncoding.Encoder IFileSystem fileSystem, IProcessFactory processFactory, ILocalizationManager localization, - Func subtitleEncoder, - IConfiguration configuration, + Lazy encodingHelperFactory, string startupOptionsFFmpegPath) { _logger = logger; @@ -69,15 +65,11 @@ namespace MediaBrowser.MediaEncoding.Encoder _fileSystem = fileSystem; _processFactory = processFactory; _localization = localization; + _encodingHelperFactory = encodingHelperFactory; _startupOptionFFmpegPath = startupOptionsFFmpegPath; - _subtitleEncoder = subtitleEncoder; - _configuration = configuration; } - private EncodingHelper EncodingHelper - => LazyInitializer.EnsureInitialized( - ref _encodingHelper, - () => new EncodingHelper(this, _fileSystem, _subtitleEncoder(), _configuration)); + private EncodingHelper EncodingHelper => _encodingHelperFactory.Value; /// public string EncoderPath => _ffmpegPath; From 129e844252bae9becd3515a6dbf3bdff35180696 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Apr 2020 02:20:37 +0900 Subject: [PATCH 121/517] use web artifacts for build step on ci --- .ci/azure-pipelines-compat.yml | 18 ++++++------ .ci/azure-pipelines-main.yml | 52 ++++++++++++++-------------------- .ci/azure-pipelines-test.yml | 35 +++++++++++------------ .ci/azure-pipelines.yml | 12 ++++---- 4 files changed, 54 insertions(+), 63 deletions(-) diff --git a/.ci/azure-pipelines-compat.yml b/.ci/azure-pipelines-compat.yml index de60d2ccb1..1ffaaf2b98 100644 --- a/.ci/azure-pipelines-compat.yml +++ b/.ci/azure-pipelines-compat.yml @@ -1,13 +1,13 @@ parameters: - - name: Packages - type: object - default: {} - - name: LinuxImage - type: string - default: "ubuntu-latest" - - name: DotNetSdkVersion - type: string - default: 3.1.100 +- name: Packages + type: object + default: {} +- name: LinuxImage + type: string + default: "ubuntu-latest" +- name: DotNetSdkVersion + type: string + default: 3.1.100 jobs: - job: CompatibilityCheck diff --git a/.ci/azure-pipelines-main.yml b/.ci/azure-pipelines-main.yml index d155624abb..59acd51ec5 100644 --- a/.ci/azure-pipelines-main.yml +++ b/.ci/azure-pipelines-main.yml @@ -20,41 +20,33 @@ jobs: submodules: true persistCredentials: true - - task: CmdLine@2 - displayName: "Clone Web Branch" - condition: and(succeeded(), or(contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + - task: DownloadPipelineArtifact@2 + displayName: "Download Web Branch" + condition: in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI', 'BuildCompletion') inputs: - script: "git clone --single-branch --branch $(Build.SourceBranchName) --depth=1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web" + path: '$(Agent.TempDirectory)' + artifact: 'jellyfin-web-production' + source: 'specific' + project: 'Jellyfin Web' + pipeline: 'Build' + runBranch: variables['Build.SourceBranch'] - - task: CmdLine@2 - displayName: "Clone Web Target" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest')) + - task: DownloadPipelineArtifact@2 + displayName: "Download Web Target" + condition: in(variables['Build.Reason'], 'PullRequest') inputs: - script: "git clone --single-branch --branch $(System.PullRequest.TargetBranch) --depth 1 https://github.com/jellyfin/jellyfin-web.git $(Agent.TempDirectory)/jellyfin-web" + path: '$(Agent.TempDirectory)' + artifact: 'jellyfin-web-production' + source: 'specific' + project: 'Jellyfin Web' + pipeline: 'Build' + runBranch: variables['System.PullRequest.TargetBranch'] - - task: NodeTool@0 - displayName: "Install Node" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) + - task: ExtractFiles@1 + displayName: "Extract Web Client" inputs: - versionSpec: "12.x" - - - task: CmdLine@2 - displayName: "Build Web Client" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - script: yarn install - workingDirectory: $(Agent.TempDirectory)/jellyfin-web - - - task: CopyFiles@2 - displayName: "Copy Web Client" - condition: and(succeeded(), or(contains(variables['System.PullRequest.TargetBranch'], 'release'), contains(variables['System.PullRequest.TargetBranch'], 'master'), contains(variables['Build.SourceBranch'], 'release'), contains(variables['Build.SourceBranch'], 'master')), eq(variables['BuildConfiguration'], 'Release'), in(variables['Build.Reason'], 'PullRequest', 'IndividualCI', 'BatchedCI', 'BuildCompletion')) - inputs: - sourceFolder: $(Agent.TempDirectory)/jellyfin-web/dist - contents: "**" - targetFolder: $(Build.SourcesDirectory)/MediaBrowser.WebDashboard/jellyfin-web - cleanTargetFolder: true - overWrite: true - flattenFolders: false + archiveFilePatterns: '$(Agent.TempDirectory)/*.zip' + destinationFolder: '$(Build.SourcesDirectory)/MediaBrowser.WebDashboard' - task: UseDotNet@2 displayName: "Update DotNet" diff --git a/.ci/azure-pipelines-test.yml b/.ci/azure-pipelines-test.yml index 4455632e15..a5d29fb619 100644 --- a/.ci/azure-pipelines-test.yml +++ b/.ci/azure-pipelines-test.yml @@ -1,26 +1,25 @@ parameters: - - name: ImageNames - type: object - default: - Linux: "ubuntu-latest" - Windows: "windows-latest" - macOS: "macos-latest" - - name: TestProjects - type: string - default: "tests/**/*Tests.csproj" - - name: DotNetSdkVersion - type: string - default: 3.1.100 +- name: ImageNames + type: object + default: + Linux: "ubuntu-latest" + Windows: "windows-latest" + macOS: "macos-latest" +- name: TestProjects + type: string + default: "tests/**/*Tests.csproj" +- name: DotNetSdkVersion + type: string + default: 3.1.100 jobs: - - job: MainTest - displayName: Main Test + - job: Test + displayName: Test strategy: matrix: ${{ each imageName in parameters.ImageNames }}: ${{ imageName.key }}: ImageName: ${{ imageName.value }} - maxParallel: 3 pool: vmImage: "$(ImageName)" steps: @@ -36,7 +35,7 @@ jobs: version: ${{ parameters.DotNetSdkVersion }} - task: DotNetCoreCLI@2 - displayName: Run .NET Core CLI tests + displayName: 'Run CLI Tests' inputs: command: "test" projects: ${{ parameters.TestProjects }} @@ -47,7 +46,7 @@ jobs: - task: Palmmedia.reportgenerator.reportgenerator-build-release-task.reportgenerator@4 condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging - displayName: ReportGenerator (merge) + displayName: 'Run ReportGenerator' inputs: reports: "$(Agent.TempDirectory)/**/coverage.cobertura.xml" targetdir: "$(Agent.TempDirectory)/merged/" @@ -56,7 +55,7 @@ jobs: ## V2 is already in the repository but it does not work "wrong number of segments" YAML error. - task: PublishCodeCoverageResults@1 condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) # !! THIS is for V1 only V2 will/should support merging - displayName: Publish Code Coverage + displayName: 'Publish Code Coverage' inputs: codeCoverageTool: "cobertura" #summaryFileLocation: '$(Agent.TempDirectory)/**/coverage.cobertura.xml' # !!THIS IS FOR V2 diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 3522cbf006..1a439c7185 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -1,12 +1,12 @@ name: $(Date:yyyyMMdd)$(Rev:.r) variables: - - name: TestProjects - value: "tests/**/*Tests.csproj" - - name: RestoreBuildProjects - value: "Jellyfin.Server/Jellyfin.Server.csproj" - - name: DotNetSdkVersion - value: 3.1.100 +- name: TestProjects + value: "tests/**/*Tests.csproj" +- name: RestoreBuildProjects + value: "Jellyfin.Server/Jellyfin.Server.csproj" +- name: DotNetSdkVersion + value: 3.1.100 pr: autoCancel: true From 8c6e1ef27e79ad38f8cd5fdc42feb2e8ee313d41 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Apr 2020 02:27:42 +0900 Subject: [PATCH 122/517] fix pipeline references --- .ci/azure-pipelines-main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci/azure-pipelines-main.yml b/.ci/azure-pipelines-main.yml index 59acd51ec5..de20412abe 100644 --- a/.ci/azure-pipelines-main.yml +++ b/.ci/azure-pipelines-main.yml @@ -27,8 +27,8 @@ jobs: path: '$(Agent.TempDirectory)' artifact: 'jellyfin-web-production' source: 'specific' - project: 'Jellyfin Web' - pipeline: 'Build' + project: 'jellyfin' + pipeline: 'Jellyfin Web' runBranch: variables['Build.SourceBranch'] - task: DownloadPipelineArtifact@2 @@ -38,8 +38,8 @@ jobs: path: '$(Agent.TempDirectory)' artifact: 'jellyfin-web-production' source: 'specific' - project: 'Jellyfin Web' - pipeline: 'Build' + project: 'jellyfin' + pipeline: 'Jellyfin Web' runBranch: variables['System.PullRequest.TargetBranch'] - task: ExtractFiles@1 From 4758e750907f28df3b324b8fb3243baf716c5a30 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Apr 2020 02:34:52 +0900 Subject: [PATCH 123/517] leave files in destination folder during extraction --- .ci/azure-pipelines-main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/azure-pipelines-main.yml b/.ci/azure-pipelines-main.yml index de20412abe..40568a3ae4 100644 --- a/.ci/azure-pipelines-main.yml +++ b/.ci/azure-pipelines-main.yml @@ -47,6 +47,7 @@ jobs: inputs: archiveFilePatterns: '$(Agent.TempDirectory)/*.zip' destinationFolder: '$(Build.SourcesDirectory)/MediaBrowser.WebDashboard' + cleanDestinationFolder: false - task: UseDotNet@2 displayName: "Update DotNet" From b937eb0c1150a650492e666016e268d2b3f463c9 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Apr 2020 14:34:31 +0900 Subject: [PATCH 124/517] change conditional for download task on ci Co-Authored-By: Mark Monteiro --- .ci/azure-pipelines-main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/azure-pipelines-main.yml b/.ci/azure-pipelines-main.yml index 40568a3ae4..456be7108f 100644 --- a/.ci/azure-pipelines-main.yml +++ b/.ci/azure-pipelines-main.yml @@ -33,7 +33,7 @@ jobs: - task: DownloadPipelineArtifact@2 displayName: "Download Web Target" - condition: in(variables['Build.Reason'], 'PullRequest') + condition: eq(variables['Build.Reason'], 'PullRequest') inputs: path: '$(Agent.TempDirectory)' artifact: 'jellyfin-web-production' From 6d35dd6b326b98995e363c64083a2ca46b2582fd Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 13 Apr 2020 13:13:48 -0400 Subject: [PATCH 125/517] Clean up SecurityException - Remove unused SecurityExceptionType - Add missing constructor for InnerException - Add missing documentation --- .../HttpServer/Security/AuthService.cs | 30 ++++------------- MediaBrowser.Api/UserService.cs | 2 +- .../Net/SecurityException.cs | 32 ++++++++++++++----- 3 files changed, 31 insertions(+), 33 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 58421aaf19..1360a5e0ce 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -108,18 +108,12 @@ namespace Emby.Server.Implementations.HttpServer.Security { if (user.Policy.IsDisabled) { - throw new SecurityException("User account has been disabled.") - { - SecurityExceptionType = SecurityExceptionType.Unauthenticated - }; + throw new SecurityException("User account has been disabled."); } if (!user.Policy.EnableRemoteAccess && !_networkManager.IsInLocalNetwork(request.RemoteIp)) { - throw new SecurityException("User account has been disabled.") - { - SecurityExceptionType = SecurityExceptionType.Unauthenticated - }; + throw new SecurityException("User account has been disabled."); } if (!user.Policy.IsAdministrator @@ -128,10 +122,7 @@ namespace Emby.Server.Implementations.HttpServer.Security { request.Response.Headers.Add("X-Application-Error-Code", "ParentalControl"); - throw new SecurityException("This user account is not allowed access at this time.") - { - SecurityExceptionType = SecurityExceptionType.ParentalControl - }; + throw new SecurityException("This user account is not allowed access at this time."); } } @@ -190,10 +181,7 @@ namespace Emby.Server.Implementations.HttpServer.Security { if (user == null || !user.Policy.IsAdministrator) { - throw new SecurityException("User does not have admin access.") - { - SecurityExceptionType = SecurityExceptionType.Unauthenticated - }; + throw new SecurityException("User does not have admin access."); } } @@ -201,10 +189,7 @@ namespace Emby.Server.Implementations.HttpServer.Security { if (user == null || !user.Policy.EnableContentDeletion) { - throw new SecurityException("User does not have delete access.") - { - SecurityExceptionType = SecurityExceptionType.Unauthenticated - }; + throw new SecurityException("User does not have delete access."); } } @@ -212,10 +197,7 @@ namespace Emby.Server.Implementations.HttpServer.Security { if (user == null || !user.Policy.EnableContentDownloading) { - throw new SecurityException("User does not have download access.") - { - SecurityExceptionType = SecurityExceptionType.Unauthenticated - }; + throw new SecurityException("User does not have download access."); } } } diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 4015143497..78fc6c6941 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -426,7 +426,7 @@ namespace MediaBrowser.Api catch (SecurityException e) { // rethrow adding IP address to message - throw new SecurityException($"[{Request.RemoteIp}] {e.Message}"); + throw new SecurityException($"[{Request.RemoteIp}] {e.Message}", e); } } diff --git a/MediaBrowser.Controller/Net/SecurityException.cs b/MediaBrowser.Controller/Net/SecurityException.cs index 3ccecf0eb8..a5b94ea5e3 100644 --- a/MediaBrowser.Controller/Net/SecurityException.cs +++ b/MediaBrowser.Controller/Net/SecurityException.cs @@ -2,20 +2,36 @@ using System; namespace MediaBrowser.Controller.Net { + /// + /// The exception that is thrown when a user is authenticated, but not authorized to access a requested resource. + /// public class SecurityException : Exception { + /// + /// Initializes a new instance of the class. + /// + public SecurityException() + : base() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. public SecurityException(string message) : base(message) { - } - public SecurityExceptionType SecurityExceptionType { get; set; } - } - - public enum SecurityExceptionType - { - Unauthenticated = 0, - ParentalControl = 1 + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error + /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified. + public SecurityException(string message, Exception innerException) + : base(message, innerException) + { + } } } From 53380689ad00f00efc0c1790f1d25d08c95d7f2d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 13 Apr 2020 13:17:46 -0400 Subject: [PATCH 126/517] Return correct status codes for authentication and authorization errors - Use AuthenticatonException to return 401 - Use SecurityException to return 403 - Update existing throws to throw the correct exception for the circumstance --- .../HttpServer/HttpListenerHost.cs | 5 ++++- .../HttpServer/Security/AuthService.cs | 7 ++++--- Emby.Server.Implementations/Library/UserManager.cs | 11 ++++------- Emby.Server.Implementations/Session/SessionManager.cs | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 5ae65a4e3d..f496ff1ba1 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -14,6 +14,7 @@ using Emby.Server.Implementations.Services; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller; +using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Events; @@ -230,7 +231,8 @@ namespace Emby.Server.Implementations.HttpServer switch (ex) { case ArgumentException _: return 400; - case SecurityException _: return 401; + case AuthenticationException _: return 401; + case SecurityException _: return 403; case DirectoryNotFoundException _: case FileNotFoundException _: case ResourceNotFoundException _: return 404; @@ -550,6 +552,7 @@ namespace Emby.Server.Implementations.HttpServer || ex is IOException || ex is OperationCanceledException || ex is SecurityException + || ex is AuthenticationException || ex is FileNotFoundException; await ErrorHandler(ex, httpReq, !ignoreStackTrace, urlToLog).ConfigureAwait(false); } diff --git a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs index 1360a5e0ce..256b24924e 100644 --- a/Emby.Server.Implementations/HttpServer/Security/AuthService.cs +++ b/Emby.Server.Implementations/HttpServer/Security/AuthService.cs @@ -2,6 +2,7 @@ using System; using System.Linq; +using System.Security.Authentication; using Emby.Server.Implementations.SocketSharp; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; @@ -68,7 +69,7 @@ namespace Emby.Server.Implementations.HttpServer.Security if (user == null && auth.UserId != Guid.Empty) { - throw new SecurityException("User with Id " + auth.UserId + " not found"); + throw new AuthenticationException("User with Id " + auth.UserId + " not found"); } if (user != null) @@ -212,14 +213,14 @@ namespace Emby.Server.Implementations.HttpServer.Security { if (string.IsNullOrEmpty(token)) { - throw new SecurityException("Access token is required."); + throw new AuthenticationException("Access token is required."); } var info = GetTokenInfo(request); if (info == null) { - throw new SecurityException("Access token is invalid or expired."); + throw new AuthenticationException("Access token is invalid or expired."); } //if (!string.IsNullOrEmpty(info.UserId)) diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs index 7b17cc913f..f92cb6ae6d 100644 --- a/Emby.Server.Implementations/Library/UserManager.cs +++ b/Emby.Server.Implementations/Library/UserManager.cs @@ -20,6 +20,7 @@ using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Persistence; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Providers; @@ -324,21 +325,17 @@ namespace Emby.Server.Implementations.Library if (user.Policy.IsDisabled) { - throw new AuthenticationException( - string.Format( - CultureInfo.InvariantCulture, - "The {0} account is currently disabled. Please consult with your administrator.", - user.Name)); + throw new SecurityException($"The {user.Name} account is currently disabled. Please consult with your administrator."); } if (!user.Policy.EnableRemoteAccess && !_networkManager.IsInLocalNetwork(remoteEndPoint)) { - throw new AuthenticationException("Forbidden."); + throw new SecurityException("Forbidden."); } if (!user.IsParentalScheduleAllowed()) { - throw new AuthenticationException("User is not allowed access at this time."); + throw new SecurityException("User is not allowed access at this time."); } // Update LastActivityDate and LastLoginDate, then save diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index de768333d8..c93c02c480 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -1414,7 +1414,7 @@ namespace Emby.Server.Implementations.Session if (user == null) { AuthenticationFailed?.Invoke(this, new GenericEventArgs(request)); - throw new SecurityException("Invalid username or password entered."); + throw new AuthenticationException("Invalid username or password entered."); } if (!string.IsNullOrEmpty(request.DeviceId) From 98044e77935afdd4ff00a65d43b17d285fea82c7 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 13 Apr 2020 13:18:12 -0400 Subject: [PATCH 127/517] Document AuthenticationException correctly --- .../Authentication/AuthenticationException.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/MediaBrowser.Controller/Authentication/AuthenticationException.cs b/MediaBrowser.Controller/Authentication/AuthenticationException.cs index 62eca3ea9f..28209f6391 100644 --- a/MediaBrowser.Controller/Authentication/AuthenticationException.cs +++ b/MediaBrowser.Controller/Authentication/AuthenticationException.cs @@ -7,23 +7,29 @@ namespace MediaBrowser.Controller.Authentication /// public class AuthenticationException : Exception { - /// + /// + /// Initializes a new instance of the class. + /// public AuthenticationException() : base() { - } - /// + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. public AuthenticationException(string message) : base(message) { - } - /// + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error + /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified. public AuthenticationException(string message, Exception innerException) : base(message, innerException) { - } } } From 9c7b3850f98633570cfb426e020153363921ce40 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 13 Apr 2020 14:55:24 -0400 Subject: [PATCH 128/517] Throw AuthenticationException instead of ArgumentNullException when a user does not exist --- .../Library/DefaultAuthenticationProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs index ab036eca7a..52c8facc3e 100644 --- a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs +++ b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs @@ -47,7 +47,7 @@ namespace Emby.Server.Implementations.Library { if (resolvedUser == null) { - throw new ArgumentNullException(nameof(resolvedUser)); + throw new AuthenticationException($"Specified user does not exist."); } bool success = false; From a8c3951c1798ced5c10631da7d9ca64731a12f26 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 13 Apr 2020 15:26:49 -0400 Subject: [PATCH 129/517] Only show developer exception page for 500 server exceptions Other response codes should be returned as normal --- .../HttpServer/HttpListenerHost.cs | 89 ++++++++++--------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index f496ff1ba1..4c69b35e2a 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -241,40 +241,38 @@ namespace Emby.Server.Implementations.HttpServer } } - private async Task ErrorHandler(Exception ex, IRequest httpReq, bool logExceptionStackTrace, string urlToLog) + private async Task ErrorHandler(Exception ex, IRequest httpReq, int statusCode, string urlToLog) { - try - { - ex = GetActualException(ex); - - if (logExceptionStackTrace) - { - _logger.LogError(ex, "Error processing request. URL: {Url}", urlToLog); - } - else - { - _logger.LogError("Error processing request: {Message}. URL: {Url}", ex.Message.TrimEnd('.'), urlToLog); - } + bool ignoreStackTrace = + ex is SocketException + || ex is IOException + || ex is OperationCanceledException + || ex is SecurityException + || ex is AuthenticationException + || ex is FileNotFoundException; - var httpRes = httpReq.Response; - - if (httpRes.HasStarted) - { - return; - } + if (ignoreStackTrace) + { + _logger.LogError("Error processing request: {Message}. URL: {Url}", ex.Message.TrimEnd('.'), urlToLog); + } + else + { + _logger.LogError(ex, "Error processing request. URL: {Url}", urlToLog); + } - var statusCode = GetStatusCode(ex); - httpRes.StatusCode = statusCode; + var httpRes = httpReq.Response; - var errContent = NormalizeExceptionMessage(ex.Message); - httpRes.ContentType = "text/plain"; - httpRes.ContentLength = errContent.Length; - await httpRes.WriteAsync(errContent).ConfigureAwait(false); - } - catch (Exception errorEx) + if (httpRes.HasStarted) { - _logger.LogError(errorEx, "Error this.ProcessRequest(context)(Exception while writing error to the response). URL: {Url}", urlToLog); + return; } + + httpRes.StatusCode = statusCode; + + var errContent = NormalizeExceptionMessage(ex.Message); + httpRes.ContentType = "text/plain"; + httpRes.ContentLength = errContent.Length; + await httpRes.WriteAsync(errContent).ConfigureAwait(false); } private string NormalizeExceptionMessage(string msg) @@ -538,23 +536,32 @@ namespace Emby.Server.Implementations.HttpServer throw new FileNotFoundException(); } } - catch (Exception ex) + catch (Exception requestEx) { - // Do not handle exceptions manually when in development mode - // The framework-defined development exception page will be returned instead - if (_hostEnvironment.IsDevelopment()) + try { - throw; + var requestInnerEx = GetActualException(requestEx); + var statusCode = GetStatusCode(requestInnerEx); + + // Do not handle 500 server exceptions manually when in development mode + // The framework-defined development exception page will be returned instead + if (statusCode == 500 && _hostEnvironment.IsDevelopment()) + { + throw; + } + + await ErrorHandler(requestInnerEx, httpReq, statusCode, urlToLog).ConfigureAwait(false); } + catch (Exception handlerException) + { + var aggregateEx = new AggregateException("Error while handling request exception", requestEx, handlerException); + _logger.LogError(aggregateEx, "Error while handling exception in response to {Url}", urlToLog); - bool ignoreStackTrace = - ex is SocketException - || ex is IOException - || ex is OperationCanceledException - || ex is SecurityException - || ex is AuthenticationException - || ex is FileNotFoundException; - await ErrorHandler(ex, httpReq, !ignoreStackTrace, urlToLog).ConfigureAwait(false); + if (_hostEnvironment.IsDevelopment()) + { + throw aggregateEx; + } + } } finally { From 8b4b4b4127945354731036e13ca0b5366134958d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Mon, 13 Apr 2020 16:10:55 -0400 Subject: [PATCH 130/517] Do not return the exception message to the client for AuthenticationExceptions --- .../HttpServer/HttpListenerHost.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 4c69b35e2a..211a0c1d99 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -269,25 +269,24 @@ namespace Emby.Server.Implementations.HttpServer httpRes.StatusCode = statusCode; - var errContent = NormalizeExceptionMessage(ex.Message); + var errContent = NormalizeExceptionMessage(ex) ?? string.Empty; httpRes.ContentType = "text/plain"; httpRes.ContentLength = errContent.Length; await httpRes.WriteAsync(errContent).ConfigureAwait(false); } - private string NormalizeExceptionMessage(string msg) + private string NormalizeExceptionMessage(Exception ex) { - if (msg == null) + // Do not expose the exception message for AuthenticationException + if (ex is AuthenticationException) { - return string.Empty; + return null; } // Strip any information we don't want to reveal - - msg = msg.Replace(_config.ApplicationPaths.ProgramSystemPath, string.Empty, StringComparison.OrdinalIgnoreCase); - msg = msg.Replace(_config.ApplicationPaths.ProgramDataPath, string.Empty, StringComparison.OrdinalIgnoreCase); - - return msg; + return ex.Message + ?.Replace(_config.ApplicationPaths.ProgramSystemPath, string.Empty, StringComparison.OrdinalIgnoreCase) + .Replace(_config.ApplicationPaths.ProgramDataPath, string.Empty, StringComparison.OrdinalIgnoreCase); } /// From 9c679b657045734eef9cbd1c2160602592a30b41 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 14:45:57 -0400 Subject: [PATCH 131/517] Clean up and document ActivityLogEntryPoint.cs --- .../Activity/ActivityLogEntryPoint.cs | 75 +++++++------------ 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index d900520b2a..e025417d13 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Collections.Generic; using System.Globalization; @@ -27,6 +25,10 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Activity { + /// + /// The activity log entry point. + /// . + /// public sealed class ActivityLogEntryPoint : IServerEntryPoint { private readonly ILogger _logger; @@ -42,16 +44,15 @@ namespace Emby.Server.Implementations.Activity /// /// Initializes a new instance of the class. /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// + /// The logger. + /// The session manager. + /// The device manager. + /// The task manager. + /// The activity manager. + /// The localization manager. + /// The installation manager. + /// The subtitle manager. + /// The user manager. public ActivityLogEntryPoint( ILogger logger, ISessionManager sessionManager, @@ -74,6 +75,7 @@ namespace Emby.Server.Implementations.Activity _userManager = userManager; } + /// public Task RunAsync() { _taskManager.TaskCompleted += OnTaskCompleted; @@ -136,7 +138,7 @@ namespace Emby.Server.Implementations.Activity CultureInfo.InvariantCulture, _localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"), e.Provider, - Emby.Notifications.NotificationEntryPoint.GetItemName(e.Item)), + Notifications.NotificationEntryPoint.GetItemName(e.Item)), Type = "SubtitleDownloadFailure", ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture), ShortOverview = e.Exception.Message @@ -259,31 +261,20 @@ namespace Emby.Server.Implementations.Activity private void OnSessionEnded(object sender, SessionEventArgs e) { - string name; var session = e.SessionInfo; if (string.IsNullOrEmpty(session.UserName)) { - name = string.Format( - CultureInfo.InvariantCulture, - _localization.GetLocalizedString("DeviceOfflineWithName"), - session.DeviceName); - - // Causing too much spam for now return; } - else + + CreateLogEntry(new ActivityLogEntry { - name = string.Format( + Name = string.Format( CultureInfo.InvariantCulture, _localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, - session.DeviceName); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = name, + session.DeviceName), Type = "SessionEnded", ShortOverview = string.Format( CultureInfo.InvariantCulture, @@ -382,31 +373,20 @@ namespace Emby.Server.Implementations.Activity private void OnSessionStarted(object sender, SessionEventArgs e) { - string name; var session = e.SessionInfo; if (string.IsNullOrEmpty(session.UserName)) { - name = string.Format( - CultureInfo.InvariantCulture, - _localization.GetLocalizedString("DeviceOnlineWithName"), - session.DeviceName); - - // Causing too much spam for now return; } - else + + CreateLogEntry(new ActivityLogEntry { - name = string.Format( + Name = string.Format( CultureInfo.InvariantCulture, _localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, - session.DeviceName); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = name, + session.DeviceName), Type = "SessionStarted", ShortOverview = string.Format( CultureInfo.InvariantCulture, @@ -485,8 +465,7 @@ namespace Emby.Server.Implementations.Activity var result = e.Result; var task = e.Task; - var activityTask = task.ScheduledTask as IConfigurableScheduledTask; - if (activityTask != null && !activityTask.IsLogged) + if (task.ScheduledTask is IConfigurableScheduledTask activityTask && !activityTask.IsLogged) { return; } @@ -560,6 +539,8 @@ namespace Emby.Server.Implementations.Activity /// /// Constructs a user-friendly string for this TimeSpan instance. /// + /// The timespan. + /// The user-friendly string. public static string ToUserFriendlyString(TimeSpan span) { const int DaysInYear = 365; @@ -574,7 +555,7 @@ namespace Emby.Server.Implementations.Activity { int years = days / DaysInYear; values.Add(CreateValueString(years, "year")); - days = days % DaysInYear; + days %= DaysInYear; } // Number of months @@ -582,7 +563,7 @@ namespace Emby.Server.Implementations.Activity { int months = days / DaysInMonth; values.Add(CreateValueString(months, "month")); - days = days % DaysInMonth; + days %= DaysInMonth; } // Number of days From af4d617df22301d2740f1286727280bc1865f889 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 14:50:19 -0400 Subject: [PATCH 132/517] Clean up and document ActivityManager.cs --- .../Activity/ActivityManager.cs | 16 ++++++++++------ Emby.Server.Implementations/ApplicationHost.cs | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs index ee10845cfa..2d2dc8e61e 100644 --- a/Emby.Server.Implementations/Activity/ActivityManager.cs +++ b/Emby.Server.Implementations/Activity/ActivityManager.cs @@ -1,32 +1,34 @@ -#pragma warning disable CS1591 - using System; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Activity; using MediaBrowser.Model.Events; using MediaBrowser.Model.Querying; -using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Activity { + /// public class ActivityManager : IActivityManager { + /// public event EventHandler> EntryCreated; private readonly IActivityRepository _repo; - private readonly ILogger _logger; private readonly IUserManager _userManager; + /// + /// Initializes a new instance of the class. + /// + /// The activity repository. + /// The user manager. public ActivityManager( - ILoggerFactory loggerFactory, IActivityRepository repo, IUserManager userManager) { - _logger = loggerFactory.CreateLogger(nameof(ActivityManager)); _repo = repo; _userManager = userManager; } + /// public void Create(ActivityLogEntry entry) { entry.Date = DateTime.UtcNow; @@ -36,6 +38,7 @@ namespace Emby.Server.Implementations.Activity EntryCreated?.Invoke(this, new GenericEventArgs(entry)); } + /// public QueryResult GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit) { var result = _repo.GetActivityLogEntries(minDate, hasUserId, startIndex, limit); @@ -59,6 +62,7 @@ namespace Emby.Server.Implementations.Activity return result; } + /// public QueryResult GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit) { return GetActivityLogEntries(minDate, null, startIndex, limit); diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 81a80ddb26..7e80900f49 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -833,7 +833,7 @@ namespace Emby.Server.Implementations var activityLogRepo = GetActivityLogRepository(); serviceCollection.AddSingleton(activityLogRepo); - serviceCollection.AddSingleton(new ActivityManager(LoggerFactory, activityLogRepo, UserManager)); + serviceCollection.AddSingleton(new ActivityManager(activityLogRepo, UserManager)); var authContext = new AuthorizationContext(AuthenticationRepository, UserManager); serviceCollection.AddSingleton(authContext); From f6899de33850ddd6ccfc4262bc6c2fd836bfc32d Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:04:54 -0400 Subject: [PATCH 133/517] Clean up and document ActivityRepository.cs --- .../Activity/ActivityRepository.cs | 180 +++++++++--------- 1 file changed, 87 insertions(+), 93 deletions(-) diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index 7be72319ea..697ad7fcc0 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Collections.Generic; using System.Globalization; @@ -15,11 +13,18 @@ using SQLitePCL.pretty; namespace Emby.Server.Implementations.Activity { + /// public class ActivityRepository : BaseSqliteRepository, IActivityRepository { private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); private readonly IFileSystem _fileSystem; + /// + /// Initializes a new instance of the class. + /// + /// The logger factory. + /// The server application paths. + /// The filesystem. public ActivityRepository(ILoggerFactory loggerFactory, IServerApplicationPaths appPaths, IFileSystem fileSystem) : base(loggerFactory.CreateLogger(nameof(ActivityRepository))) { @@ -27,6 +32,9 @@ namespace Emby.Server.Implementations.Activity _fileSystem = fileSystem; } + /// + /// Initializes the . + /// public void Initialize() { try @@ -45,16 +53,14 @@ namespace Emby.Server.Implementations.Activity private void InitializeInternal() { - using (var connection = GetConnection()) + using var connection = GetConnection(); + connection.RunQueries(new[] { - connection.RunQueries(new[] - { - "create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)", - "drop index if exists idx_ActivityLogEntries" - }); + "create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)", + "drop index if exists idx_ActivityLogEntries" + }); - TryMigrate(connection); - } + TryMigrate(connection); } private void TryMigrate(ManagedConnection connection) @@ -78,6 +84,7 @@ namespace Emby.Server.Implementations.Activity private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog"; + /// public void Create(ActivityLogEntry entry) { if (entry == null) @@ -85,37 +92,38 @@ namespace Emby.Server.Implementations.Activity throw new ArgumentNullException(nameof(entry)); } - using (var connection = GetConnection()) + using var connection = GetConnection(); + connection.RunInTransaction(db => { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)")) - { - statement.TryBind("@Name", entry.Name); + using var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)"); + statement.TryBind("@Name", entry.Name); - statement.TryBind("@Overview", entry.Overview); - statement.TryBind("@ShortOverview", entry.ShortOverview); - statement.TryBind("@Type", entry.Type); - statement.TryBind("@ItemId", entry.ItemId); + statement.TryBind("@Overview", entry.Overview); + statement.TryBind("@ShortOverview", entry.ShortOverview); + statement.TryBind("@Type", entry.Type); + statement.TryBind("@ItemId", entry.ItemId); - if (entry.UserId.Equals(Guid.Empty)) - { - statement.TryBindNull("@UserId"); - } - else - { - statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture)); - } + if (entry.UserId.Equals(Guid.Empty)) + { + statement.TryBindNull("@UserId"); + } + else + { + statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture)); + } - statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); - statement.TryBind("@LogSeverity", entry.Severity.ToString()); + statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); + statement.TryBind("@LogSeverity", entry.Severity.ToString()); - statement.MoveNext(); - } - }, TransactionMode); - } + statement.MoveNext(); + }, TransactionMode); } + /// + /// Adds the provided to this repository. + /// + /// The activity log entry. + /// If entry is null. public void Update(ActivityLogEntry entry) { if (entry == null) @@ -123,38 +131,35 @@ namespace Emby.Server.Implementations.Activity throw new ArgumentNullException(nameof(entry)); } - using (var connection = GetConnection()) + using var connection = GetConnection(); + connection.RunInTransaction(db => { - connection.RunInTransaction(db => - { - using (var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id")) - { - statement.TryBind("@Id", entry.Id); + using var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id"); + statement.TryBind("@Id", entry.Id); - statement.TryBind("@Name", entry.Name); - statement.TryBind("@Overview", entry.Overview); - statement.TryBind("@ShortOverview", entry.ShortOverview); - statement.TryBind("@Type", entry.Type); - statement.TryBind("@ItemId", entry.ItemId); + statement.TryBind("@Name", entry.Name); + statement.TryBind("@Overview", entry.Overview); + statement.TryBind("@ShortOverview", entry.ShortOverview); + statement.TryBind("@Type", entry.Type); + statement.TryBind("@ItemId", entry.ItemId); - if (entry.UserId.Equals(Guid.Empty)) - { - statement.TryBindNull("@UserId"); - } - else - { - statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture)); - } + if (entry.UserId.Equals(Guid.Empty)) + { + statement.TryBindNull("@UserId"); + } + else + { + statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture)); + } - statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); - statement.TryBind("@LogSeverity", entry.Severity.ToString()); + statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue()); + statement.TryBind("@LogSeverity", entry.Severity.ToString()); - statement.MoveNext(); - } - }, TransactionMode); - } + statement.MoveNext(); + }, TransactionMode); } + /// public QueryResult GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit) { var commandText = BaseActivitySelectText; @@ -164,16 +169,10 @@ namespace Emby.Server.Implementations.Activity { whereClauses.Add("DateCreated>=@DateCreated"); } + if (hasUserId.HasValue) { - if (hasUserId.Value) - { - whereClauses.Add("UserId not null"); - } - else - { - whereClauses.Add("UserId is null"); - } + whereClauses.Add(hasUserId.Value ? "UserId not null" : "UserId is null"); } var whereTextWithoutPaging = whereClauses.Count == 0 ? @@ -216,38 +215,33 @@ namespace Emby.Server.Implementations.Activity var list = new List(); var result = new QueryResult(); - using (var connection = GetConnection(true)) - { - connection.RunInTransaction( - db => - { - var statements = PrepareAll(db, statementTexts).ToList(); + using var connection = GetConnection(true); + connection.RunInTransaction( + db => + { + var statements = PrepareAll(db, statementTexts).ToList(); - using (var statement = statements[0]) + using (var statement = statements[0]) + { + if (minDate.HasValue) { - if (minDate.HasValue) - { - statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue()); - } - - foreach (var row in statement.ExecuteQuery()) - { - list.Add(GetEntry(row)); - } + statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue()); } - using (var statement = statements[1]) - { - if (minDate.HasValue) - { - statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue()); - } + list.AddRange(statement.ExecuteQuery().Select(GetEntry)); + } - result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First(); + using (var statement = statements[1]) + { + if (minDate.HasValue) + { + statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue()); } - }, - ReadTransactionMode); - } + + result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First(); + } + }, + ReadTransactionMode); result.Items = list; return result; From 0e8f30f64b9d9f88d2593d97289ed055b7bfbd0d Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:08:20 -0400 Subject: [PATCH 134/517] Documented BaseApplicationPath constructor parameters --- Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs index bc47817438..2adc1d6c34 100644 --- a/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs +++ b/Emby.Server.Implementations/AppBase/BaseApplicationPaths.cs @@ -15,6 +15,11 @@ namespace Emby.Server.Implementations.AppBase /// /// Initializes a new instance of the class. /// + /// The program data path. + /// The log directory path. + /// The configuration directory path. + /// The cache directory path. + /// The web directory path. protected BaseApplicationPaths( string programDataPath, string logDirectoryPath, From 9cec01d8ce610fcff99a901d6685668abc96106d Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:11:21 -0400 Subject: [PATCH 135/517] Switch to using declaration --- .../AppBase/ConfigurationHelper.cs | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs index 854d7b4cbf..0b681fddfc 100644 --- a/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs +++ b/Emby.Server.Implementations/AppBase/ConfigurationHelper.cs @@ -36,24 +36,22 @@ namespace Emby.Server.Implementations.AppBase configuration = Activator.CreateInstance(type); } - using (var stream = new MemoryStream()) - { - xmlSerializer.SerializeToStream(configuration, stream); - - // Take the object we just got and serialize it back to bytes - var newBytes = stream.ToArray(); + using var stream = new MemoryStream(); + xmlSerializer.SerializeToStream(configuration, stream); - // If the file didn't exist before, or if something has changed, re-save - if (buffer == null || !buffer.SequenceEqual(newBytes)) - { - Directory.CreateDirectory(Path.GetDirectoryName(path)); + // Take the object we just got and serialize it back to bytes + var newBytes = stream.ToArray(); - // Save it after load in case we got new items - File.WriteAllBytes(path, newBytes); - } + // If the file didn't exist before, or if something has changed, re-save + if (buffer == null || !buffer.SequenceEqual(newBytes)) + { + Directory.CreateDirectory(Path.GetDirectoryName(path)); - return configuration; + // Save it after load in case we got new items + File.WriteAllBytes(path, newBytes); } + + return configuration; } } } From 90e256416942d14a4c765cfcb48e7c740fb2361c Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:16:04 -0400 Subject: [PATCH 136/517] Document and clean up ZipClient.cs --- .../Archiving/ZipClient.cs | 130 +++++++----------- 1 file changed, 53 insertions(+), 77 deletions(-) diff --git a/Emby.Server.Implementations/Archiving/ZipClient.cs b/Emby.Server.Implementations/Archiving/ZipClient.cs index 4a6e5cfd75..591ae547d6 100644 --- a/Emby.Server.Implementations/Archiving/ZipClient.cs +++ b/Emby.Server.Implementations/Archiving/ZipClient.cs @@ -22,10 +22,8 @@ namespace Emby.Server.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAll(string sourceFile, string targetPath, bool overwriteExistingFiles) { - using (var fileStream = File.OpenRead(sourceFile)) - { - ExtractAll(fileStream, targetPath, overwriteExistingFiles); - } + using var fileStream = File.OpenRead(sourceFile); + ExtractAll(fileStream, targetPath, overwriteExistingFiles); } /// @@ -36,67 +34,61 @@ namespace Emby.Server.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAll(Stream source, string targetPath, bool overwriteExistingFiles) { - using (var reader = ReaderFactory.Open(source)) + using var reader = ReaderFactory.Open(source); + var options = new ExtractionOptions { - var options = new ExtractionOptions(); - options.ExtractFullPath = true; - - if (overwriteExistingFiles) - { - options.Overwrite = true; - } + ExtractFullPath = true + }; - reader.WriteAllToDirectory(targetPath, options); + if (overwriteExistingFiles) + { + options.Overwrite = true; } + + reader.WriteAllToDirectory(targetPath, options); } + /// public void ExtractAllFromZip(Stream source, string targetPath, bool overwriteExistingFiles) { - using (var reader = ZipReader.Open(source)) + using var reader = ZipReader.Open(source); + var options = new ExtractionOptions { - var options = new ExtractionOptions(); - options.ExtractFullPath = true; + ExtractFullPath = true, + Overwrite = overwriteExistingFiles + }; - if (overwriteExistingFiles) - { - options.Overwrite = true; - } - - reader.WriteAllToDirectory(targetPath, options); - } + reader.WriteAllToDirectory(targetPath, options); } + /// public void ExtractAllFromGz(Stream source, string targetPath, bool overwriteExistingFiles) { - using (var reader = GZipReader.Open(source)) + using var reader = GZipReader.Open(source); + var options = new ExtractionOptions { - var options = new ExtractionOptions(); - options.ExtractFullPath = true; + ExtractFullPath = true, + Overwrite = overwriteExistingFiles + }; - if (overwriteExistingFiles) - { - options.Overwrite = true; - } - - reader.WriteAllToDirectory(targetPath, options); - } + reader.WriteAllToDirectory(targetPath, options); } + /// public void ExtractFirstFileFromGz(Stream source, string targetPath, string defaultFileName) { - using (var reader = GZipReader.Open(source)) + using var reader = GZipReader.Open(source); + if (reader.MoveToNextEntry()) { - if (reader.MoveToNextEntry()) + var entry = reader.Entry; + + var filename = entry.Key; + if (string.IsNullOrWhiteSpace(filename)) { - var entry = reader.Entry; - - var filename = entry.Key; - if (string.IsNullOrWhiteSpace(filename)) - { - filename = defaultFileName; - } - reader.WriteEntryToFile(Path.Combine(targetPath, filename)); + filename = defaultFileName; } + + reader.WriteEntryToFile(Path.Combine(targetPath, filename)); } } @@ -108,10 +100,8 @@ namespace Emby.Server.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAllFrom7z(string sourceFile, string targetPath, bool overwriteExistingFiles) { - using (var fileStream = File.OpenRead(sourceFile)) - { - ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles); - } + using var fileStream = File.OpenRead(sourceFile); + ExtractAllFrom7z(fileStream, targetPath, overwriteExistingFiles); } /// @@ -122,21 +112,15 @@ namespace Emby.Server.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAllFrom7z(Stream source, string targetPath, bool overwriteExistingFiles) { - using (var archive = SevenZipArchive.Open(source)) + using var archive = SevenZipArchive.Open(source); + using var reader = archive.ExtractAllEntries(); + var options = new ExtractionOptions { - using (var reader = archive.ExtractAllEntries()) - { - var options = new ExtractionOptions(); - options.ExtractFullPath = true; - - if (overwriteExistingFiles) - { - options.Overwrite = true; - } + ExtractFullPath = true, + Overwrite = overwriteExistingFiles + }; - reader.WriteAllToDirectory(targetPath, options); - } - } + reader.WriteAllToDirectory(targetPath, options); } /// @@ -147,10 +131,8 @@ namespace Emby.Server.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAllFromTar(string sourceFile, string targetPath, bool overwriteExistingFiles) { - using (var fileStream = File.OpenRead(sourceFile)) - { - ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles); - } + using var fileStream = File.OpenRead(sourceFile); + ExtractAllFromTar(fileStream, targetPath, overwriteExistingFiles); } /// @@ -161,21 +143,15 @@ namespace Emby.Server.Implementations.Archiving /// if set to true [overwrite existing files]. public void ExtractAllFromTar(Stream source, string targetPath, bool overwriteExistingFiles) { - using (var archive = TarArchive.Open(source)) + using var archive = TarArchive.Open(source); + using var reader = archive.ExtractAllEntries(); + var options = new ExtractionOptions { - using (var reader = archive.ExtractAllEntries()) - { - var options = new ExtractionOptions(); - options.ExtractFullPath = true; + ExtractFullPath = true, + Overwrite = overwriteExistingFiles + }; - if (overwriteExistingFiles) - { - options.Overwrite = true; - } - - reader.WriteAllToDirectory(targetPath, options); - } - } + reader.WriteAllToDirectory(targetPath, options); } } } From 4c0547f90c0fa1cd8a931de630899e68933e21c7 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:19:11 -0400 Subject: [PATCH 137/517] Document BrandingConfigurationFactory.cs --- .../Branding/BrandingConfigurationFactory.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs b/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs index 93000ae127..43c8cd5fa2 100644 --- a/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs +++ b/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs @@ -1,13 +1,15 @@ -#pragma warning disable CS1591 - using System.Collections.Generic; using MediaBrowser.Common.Configuration; using MediaBrowser.Model.Branding; namespace Emby.Server.Implementations.Branding { + /// + /// Branding configuration factory. + /// public class BrandingConfigurationFactory : IConfigurationFactory { + /// public IEnumerable GetConfigurations() { return new[] From 543c76a8f10f7d55b4e0d2c0ed848f40d35debda Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:28:02 -0400 Subject: [PATCH 138/517] Clean up and document ChannelDynamicMediaSourceProvider.cs --- .../Channels/ChannelDynamicMediaSourceProvider.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs index 6016fed079..c677e9fbc3 100644 --- a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs +++ b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Collections.Generic; using System.Threading; @@ -11,6 +9,9 @@ using MediaBrowser.Model.Dto; namespace Emby.Server.Implementations.Channels { + /// + /// A media source provider for channels. + /// public class ChannelDynamicMediaSourceProvider : IMediaSourceProvider { private readonly ChannelManager _channelManager; @@ -27,12 +28,9 @@ namespace Emby.Server.Implementations.Channels /// public Task> GetMediaSources(BaseItem item, CancellationToken cancellationToken) { - if (item.SourceType == SourceType.Channel) - { - return _channelManager.GetDynamicMediaSources(item, cancellationToken); - } - - return Task.FromResult>(new List()); + return item.SourceType == SourceType.Channel + ? _channelManager.GetDynamicMediaSources(item, cancellationToken) + : Task.FromResult>(new List()); } /// From 2c920cff33f8e765b79e805d96f3bc547bc7b3fc Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:29:57 -0400 Subject: [PATCH 139/517] Document ChannelImageProvider.cs --- .../Channels/ChannelImageProvider.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs index 62aeb9bcb9..c08a237fb4 100644 --- a/Emby.Server.Implementations/Channels/ChannelImageProvider.cs +++ b/Emby.Server.Implementations/Channels/ChannelImageProvider.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System.Collections.Generic; using System.Linq; using System.Threading; @@ -11,20 +9,29 @@ using MediaBrowser.Model.Entities; namespace Emby.Server.Implementations.Channels { + /// + /// An image provider for channels. + /// public class ChannelImageProvider : IDynamicImageProvider, IHasItemChangeMonitor { private readonly IChannelManager _channelManager; + /// + /// Initializes a new instance of the class. + /// + /// The channel manager. public ChannelImageProvider(IChannelManager channelManager) { _channelManager = channelManager; } + /// public IEnumerable GetSupportedImages(BaseItem item) { return GetChannel(item).GetSupportedChannelImages(); } + /// public Task GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken) { var channel = GetChannel(item); @@ -32,8 +39,10 @@ namespace Emby.Server.Implementations.Channels return channel.GetChannelImage(type, cancellationToken); } + /// public string Name => "Channel Image Provider"; + /// public bool Supports(BaseItem item) { return item is Channel; @@ -46,6 +55,7 @@ namespace Emby.Server.Implementations.Channels return ((ChannelManager)_channelManager).GetChannelProvider(channel); } + /// public bool HasChanged(BaseItem item, IDirectoryService directoryService) { return GetSupportedImages(item).Any(i => !item.HasImage(i)); From c8e26b6d46f98ab04041064a0e7db2e731360db8 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:36:29 -0400 Subject: [PATCH 140/517] Document ChannelPostScanTask.cs --- .../Channels/ChannelPostScanTask.cs | 22 ++++++++++++++----- .../Channels/RefreshChannelsScheduledTask.cs | 2 +- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs b/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs index 266d539d0a..f48b0a7faa 100644 --- a/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs +++ b/Emby.Server.Implementations/Channels/ChannelPostScanTask.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Linq; using System.Threading; @@ -11,21 +9,35 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Channels { + /// + /// Channel post scan task. + /// This task removes all non-installed channels from the database. + /// public class ChannelPostScanTask { private readonly IChannelManager _channelManager; - private readonly IUserManager _userManager; private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; - public ChannelPostScanTask(IChannelManager channelManager, IUserManager userManager, ILogger logger, ILibraryManager libraryManager) + /// + /// Initializes a new instance of the class. + /// + /// The channel manager. + /// The logger. + /// The library manager. + public ChannelPostScanTask(IChannelManager channelManager, ILogger logger, ILibraryManager libraryManager) { _channelManager = channelManager; - _userManager = userManager; _logger = logger; _libraryManager = libraryManager; } + /// + /// Runs this task. + /// + /// The progress. + /// The cancellation token. + /// The completed task. public Task Run(IProgress progress, CancellationToken cancellationToken) { CleanDatabase(cancellationToken); diff --git a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs index 367efcb134..36cec75ec8 100644 --- a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs +++ b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs @@ -63,7 +63,7 @@ namespace Emby.Server.Implementations.Channels await manager.RefreshChannels(new SimpleProgress(), cancellationToken).ConfigureAwait(false); - await new ChannelPostScanTask(_channelManager, _userManager, _logger, _libraryManager).Run(progress, cancellationToken) + await new ChannelPostScanTask(_channelManager, _logger, _libraryManager).Run(progress, cancellationToken) .ConfigureAwait(false); } From f29e6badb3d6350fc828ac58dc645dc7b166c376 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:48:06 -0400 Subject: [PATCH 141/517] Remove unused field and documented RefreshChannelsScheduledTask.cs --- .../Channels/RefreshChannelsScheduledTask.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs index 36cec75ec8..54b621e250 100644 --- a/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs +++ b/Emby.Server.Implementations/Channels/RefreshChannelsScheduledTask.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Collections.Generic; using System.Threading; @@ -7,29 +5,36 @@ using System.Threading.Tasks; using MediaBrowser.Common.Progress; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Globalization; using MediaBrowser.Model.Tasks; using Microsoft.Extensions.Logging; -using MediaBrowser.Model.Globalization; namespace Emby.Server.Implementations.Channels { + /// + /// The "Refresh Channels" scheduled task. + /// public class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask { private readonly IChannelManager _channelManager; - private readonly IUserManager _userManager; private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; private readonly ILocalizationManager _localization; + /// + /// Initializes a new instance of the class. + /// + /// The channel manager. + /// The logger. + /// The library manager. + /// The localization manager. public RefreshChannelsScheduledTask( IChannelManager channelManager, - IUserManager userManager, ILogger logger, ILibraryManager libraryManager, ILocalizationManager localization) { _channelManager = channelManager; - _userManager = userManager; _logger = logger; _libraryManager = libraryManager; _localization = localization; @@ -72,7 +77,6 @@ namespace Emby.Server.Implementations.Channels { return new[] { - // Every so often new TaskTriggerInfo { From 77df0c943b342b4b8642809fc6dbfbd6e0e8d5a7 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:50:48 -0400 Subject: [PATCH 142/517] Clean up and document CollectionImageProvider.cs --- .../Collections/CollectionImageProvider.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs index 21ba0288ec..4d9f865e06 100644 --- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs +++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System.Collections.Generic; using System.Linq; using Emby.Server.Implementations.Images; @@ -15,8 +13,18 @@ using MediaBrowser.Model.IO; namespace Emby.Server.Implementations.Collections { + /// + /// A collection image provider. + /// public class CollectionImageProvider : BaseDynamicImageProvider { + /// + /// Initializes a new instance of the class. + /// + /// The filesystem. + /// The provider manager. + /// The application paths. + /// The image processor. public CollectionImageProvider( IFileSystem fileSystem, IProviderManager providerManager, @@ -48,13 +56,10 @@ namespace Emby.Server.Implementations.Collections var episode = subItem as Episode; - if (episode != null) + var series = episode?.Series; + if (series != null && series.HasImage(ImageType.Primary)) { - var series = episode.Series; - if (series != null && series.HasImage(ImageType.Primary)) - { - return series; - } + return series; } if (subItem.HasImage(ImageType.Primary)) From ddd8120aabc0754660e3f282408523932b61dd77 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 15:57:05 -0400 Subject: [PATCH 143/517] Clean up and document CollectionManager.cs --- .../Collections/CollectionManager.cs | 37 ++++++++++++++++--- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index 3219528749..297e8327a5 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Collections.Generic; using System.Globalization; @@ -23,6 +21,7 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Collections { + /// public class CollectionManager : ICollectionManager { private readonly ILibraryManager _libraryManager; @@ -33,6 +32,16 @@ namespace Emby.Server.Implementations.Collections private readonly ILocalizationManager _localizationManager; private readonly IApplicationPaths _appPaths; + /// + /// Initializes a new instance of the class. + /// + /// The library manager. + /// The application paths. + /// The localization manager. + /// The filesystem. + /// The library monitor. + /// The logger factory. + /// The provider manager. public CollectionManager( ILibraryManager libraryManager, IApplicationPaths appPaths, @@ -51,8 +60,13 @@ namespace Emby.Server.Implementations.Collections _appPaths = appPaths; } + /// public event EventHandler CollectionCreated; + + /// public event EventHandler ItemsAddedToCollection; + + /// public event EventHandler ItemsRemovedFromCollection; private IEnumerable FindFolders(string path) @@ -114,6 +128,7 @@ namespace Emby.Server.Implementations.Collections folder.GetChildren(user, true).OfType(); } + /// public BoxSet CreateCollection(CollectionCreationOptions options) { var name = options.Name; @@ -178,11 +193,13 @@ namespace Emby.Server.Implementations.Collections } } + /// public void AddToCollection(Guid collectionId, IEnumerable ids) { AddToCollection(collectionId, ids, true, new MetadataRefreshOptions(new DirectoryService(_fileSystem))); } + /// public void AddToCollection(Guid collectionId, IEnumerable ids) { AddToCollection(collectionId, ids.Select(i => i.ToString("N", CultureInfo.InvariantCulture)), true, new MetadataRefreshOptions(new DirectoryService(_fileSystem))); @@ -246,11 +263,13 @@ namespace Emby.Server.Implementations.Collections } } + /// public void RemoveFromCollection(Guid collectionId, IEnumerable itemIds) { RemoveFromCollection(collectionId, itemIds.Select(i => new Guid(i))); } + /// public void RemoveFromCollection(Guid collectionId, IEnumerable itemIds) { var collection = _libraryManager.GetItemById(collectionId) as BoxSet; @@ -301,6 +320,7 @@ namespace Emby.Server.Implementations.Collections }); } + /// public IEnumerable CollapseItemsWithinBoxSets(IEnumerable items, User user) { var results = new Dictionary(); @@ -309,9 +329,7 @@ namespace Emby.Server.Implementations.Collections foreach (var item in items) { - var grouping = item as ISupportsBoxSetGrouping; - - if (grouping == null) + if (!(item is ISupportsBoxSetGrouping)) { results[item.Id] = item; } @@ -341,12 +359,21 @@ namespace Emby.Server.Implementations.Collections } } + /// + /// The collection manager entry point. + /// public sealed class CollectionManagerEntryPoint : IServerEntryPoint { private readonly CollectionManager _collectionManager; private readonly IServerConfigurationManager _config; private readonly ILogger _logger; + /// + /// Initializes a new instance of the class. + /// + /// The collection manager. + /// The server configuration manager. + /// The logger. public CollectionManagerEntryPoint( ICollectionManager collectionManager, IServerConfigurationManager config, From ecaae2c8de3bf03d3a74de865546dc6b14c06b12 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 16:01:21 -0400 Subject: [PATCH 144/517] Clean up and document ServerConfigurationManager.cs --- .../Configuration/ServerConfigurationManager.cs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs index f407317ec7..0ff70decae 100644 --- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -69,21 +69,16 @@ namespace Emby.Server.Implementations.Configuration /// private void UpdateMetadataPath() { - if (string.IsNullOrWhiteSpace(Configuration.MetadataPath)) - { - ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Path.Combine(ApplicationPaths.ProgramDataPath, "metadata"); - } - else - { - ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = Configuration.MetadataPath; - } + ((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrWhiteSpace(Configuration.MetadataPath) + ? Path.Combine(ApplicationPaths.ProgramDataPath, "metadata") + : Configuration.MetadataPath; } /// /// Replaces the configuration. /// /// The new configuration. - /// + /// If the configuration path doesn't exist. public override void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration) { var newConfig = (ServerConfiguration)newConfiguration; From fd750a9c79a8bb39ecfab053315f39ea54d0f53b Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 16:13:41 -0400 Subject: [PATCH 145/517] Clean up and document CryptographyProvider.cs --- .../Cryptography/CryptographyProvider.cs | 41 ++++++++----------- 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs index de83b023d7..a037415a95 100644 --- a/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs +++ b/Emby.Server.Implementations/Cryptography/CryptographyProvider.cs @@ -31,7 +31,7 @@ namespace Emby.Server.Implementations.Cryptography private RandomNumberGenerator _randomNumberGenerator; - private bool _disposed = false; + private bool _disposed; /// /// Initializes a new instance of the class. @@ -56,15 +56,13 @@ namespace Emby.Server.Implementations.Cryptography { // downgrading for now as we need this library to be dotnetstandard compliant // with this downgrade we'll add a check to make sure we're on the downgrade method at the moment - if (method == DefaultHashMethod) + if (method != DefaultHashMethod) { - using (var r = new Rfc2898DeriveBytes(bytes, salt, iterations)) - { - return r.GetBytes(32); - } + throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}"); } - throw new CryptographicException($"Cannot currently use PBKDF2 with requested hash method: {method}"); + using var r = new Rfc2898DeriveBytes(bytes, salt, iterations); + return r.GetBytes(32); } /// @@ -74,25 +72,22 @@ namespace Emby.Server.Implementations.Cryptography { return PBKDF2(hashMethod, bytes, salt, DefaultIterations); } - else if (_supportedHashMethods.Contains(hashMethod)) + + if (!_supportedHashMethods.Contains(hashMethod)) + { + throw new CryptographicException($"Requested hash method is not supported: {hashMethod}"); + } + + using var h = HashAlgorithm.Create(hashMethod); + if (salt.Length == 0) { - using (var h = HashAlgorithm.Create(hashMethod)) - { - if (salt.Length == 0) - { - return h.ComputeHash(bytes); - } - else - { - byte[] salted = new byte[bytes.Length + salt.Length]; - Array.Copy(bytes, salted, bytes.Length); - Array.Copy(salt, 0, salted, bytes.Length, salt.Length); - return h.ComputeHash(salted); - } - } + return h.ComputeHash(bytes); } - throw new CryptographicException($"Requested hash method is not supported: {hashMethod}"); + byte[] salted = new byte[bytes.Length + salt.Length]; + Array.Copy(bytes, salted, bytes.Length); + Array.Copy(salt, 0, salted, bytes.Length, salt.Length); + return h.ComputeHash(salted); } /// From a54dca09d8c581bc2f64235d2d9a07278f5c02c4 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 14 Apr 2020 19:34:38 -0400 Subject: [PATCH 146/517] Added the last missing documentation --- .../Collections/CollectionImageProvider.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs index 4d9f865e06..c69a07e83e 100644 --- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs +++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs @@ -34,6 +34,7 @@ namespace Emby.Server.Implementations.Collections { } + /// protected override bool Supports(BaseItem item) { // Right now this is the only way to prevent this image from getting created ahead of internet image providers @@ -45,6 +46,7 @@ namespace Emby.Server.Implementations.Collections return base.Supports(item); } + /// protected override IReadOnlyList GetItemsWithImages(BaseItem item) { var playlist = (BoxSet)item; @@ -85,6 +87,7 @@ namespace Emby.Server.Implementations.Collections .ToList(); } + /// protected override string CreateImage(BaseItem item, IReadOnlyCollection itemsWithImages, string outputPathWithoutExtension, ImageType imageType, int imageIndex) { return CreateSingleImage(itemsWithImages, outputPathWithoutExtension, ImageType.Primary); From 38dae51ccf93e3b3a266007a9aad1ab980d0bb05 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sat, 11 Apr 2020 19:36:28 +0200 Subject: [PATCH 147/517] Minor IAsyncDisposable improvements --- MediaBrowser.Api/Images/RemoteImageService.cs | 13 ++++++---- MediaBrowser.Api/ItemLookupService.cs | 14 ++++++---- .../Playback/Hls/BaseHlsService.cs | 26 +++++++++++-------- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index 222bb34d31..23bf547125 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -265,17 +265,20 @@ namespace MediaBrowser.Api.Images { Url = url, BufferContent = false - }).ConfigureAwait(false); - var ext = result.ContentType.Split('/').Last(); + var ext = result.ContentType.Split('/')[^1]; var fullCachePath = GetFullCachePath(urlHash + "." + ext); Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); - using (var stream = result.Content) + var stream = result.Content; + await using (stream.ConfigureAwait(false)) { - using var filestream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); - await stream.CopyToAsync(filestream).ConfigureAwait(false); + var filestream = new FileStream(fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); + await using (filestream.ConfigureAwait(false)) + { + await stream.CopyToAsync(filestream).ConfigureAwait(false); + } } Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index 0bbe7e1cfa..68e3dfa59c 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -299,22 +299,26 @@ namespace MediaBrowser.Api { var result = await _providerManager.GetSearchImage(providerName, url, CancellationToken.None).ConfigureAwait(false); - var ext = result.ContentType.Split('/').Last(); + var ext = result.ContentType.Split('/')[^1]; var fullCachePath = GetFullCachePath(urlHash + "." + ext); Directory.CreateDirectory(Path.GetDirectoryName(fullCachePath)); - using (var stream = result.Content) + var stream = result.Content; + + await using (stream.ConfigureAwait(false)) { - using var fileStream = new FileStream( + var fileStream = new FileStream( fullCachePath, FileMode.Create, FileAccess.Write, FileShare.Read, IODefaults.FileStreamBufferSize, true); - - await stream.CopyToAsync(fileStream).ConfigureAwait(false); + await using (fileStream.ConfigureAwait(false)) + { + await stream.CopyToAsync(fileStream).ConfigureAwait(false); + } } Directory.CreateDirectory(Path.GetDirectoryName(pointerCachePath)); diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 52962366c6..4213193bac 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -209,24 +209,28 @@ namespace MediaBrowser.Api.Playback.Hls try { // Need to use FileShare.ReadWrite because we're reading the file at the same time it's being written - using var fileStream = GetPlaylistFileStream(playlist); - using var reader = new StreamReader(fileStream); - var count = 0; - - while (!reader.EndOfStream) + var fileStream = GetPlaylistFileStream(playlist); + await using (fileStream.ConfigureAwait(false)) { - var line = reader.ReadLine(); + using var reader = new StreamReader(fileStream); + var count = 0; - if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) + while (!reader.EndOfStream) { - count++; - if (count >= segmentCount) + var line = await reader.ReadLineAsync().ConfigureAwait(false); + + if (line.IndexOf("#EXTINF:", StringComparison.OrdinalIgnoreCase) != -1) { - Logger.LogDebug("Finished waiting for {0} segments in {1}", segmentCount, playlist); - return; + count++; + if (count >= segmentCount) + { + Logger.LogDebug("Finished waiting for {0} segments in {1}", segmentCount, playlist); + return; + } } } } + await Task.Delay(100, cancellationToken).ConfigureAwait(false); } catch (IOException) From 10afa4509db6fc7e3c2e7dd6ccc8997dfe3b10f9 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 15 Apr 2020 11:14:54 +0200 Subject: [PATCH 148/517] Log exception --- Emby.Server.Implementations/Data/SqliteItemRepository.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index d3b3f7b7af..aac0d8d38a 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -1995,9 +1995,9 @@ namespace Emby.Server.Implementations.Data { chapter.ImageTag = ImageProcessor.GetImageCacheTag(item, chapter); } - catch + catch (Exception ex) { - + Logger.LogError(ex, "Failed to create image cache tag."); } } } From 27ce10d0c13bc30fa1b08682e13bab67784b289d Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Wed, 15 Apr 2020 11:18:13 +0200 Subject: [PATCH 149/517] Fix release build --- MediaBrowser.Model/Providers/ImageProviderInfo.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MediaBrowser.Model/Providers/ImageProviderInfo.cs b/MediaBrowser.Model/Providers/ImageProviderInfo.cs index d1a7c25069..19af81c857 100644 --- a/MediaBrowser.Model/Providers/ImageProviderInfo.cs +++ b/MediaBrowser.Model/Providers/ImageProviderInfo.cs @@ -7,6 +7,11 @@ namespace MediaBrowser.Model.Providers /// public class ImageProviderInfo { + /// + /// Initializes a new instance of the class. + /// + /// The name of the image provider. + /// The image types supported by the image provider. public ImageProviderInfo(string name, ImageType[] supportedImages) { Name = name; From daed41815f23795aad7f54965a8ef7eae44a1e08 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Wed, 15 Apr 2020 08:56:00 -0400 Subject: [PATCH 150/517] Add missing punctuation in xml comment Co-Authored-By: Bond-009 --- .../Authentication/AuthenticationException.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Authentication/AuthenticationException.cs b/MediaBrowser.Controller/Authentication/AuthenticationException.cs index 28209f6391..081f877f72 100644 --- a/MediaBrowser.Controller/Authentication/AuthenticationException.cs +++ b/MediaBrowser.Controller/Authentication/AuthenticationException.cs @@ -25,7 +25,7 @@ namespace MediaBrowser.Controller.Authentication /// /// Initializes a new instance of the class. /// - /// The message that describes the error + /// The message that describes the error. /// The exception that is the cause of the current exception, or a null reference if no inner exception is specified. public AuthenticationException(string message, Exception innerException) : base(message, innerException) From c4e6329e58f36c340a65fa216a058ce1fee5507f Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Wed, 15 Apr 2020 15:00:45 -0400 Subject: [PATCH 151/517] Clean up and document ChannelManager.cs and implement suggestions --- .../Activity/ActivityLogEntryPoint.cs | 1 - .../Activity/ActivityManager.cs | 4 +- .../Activity/ActivityRepository.cs | 4 +- .../ChannelDynamicMediaSourceProvider.cs | 3 +- .../Channels/ChannelManager.cs | 227 ++++++++++-------- .../Collections/CollectionManager.cs | 4 +- 6 files changed, 140 insertions(+), 103 deletions(-) diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index e025417d13..2ea6789765 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -27,7 +27,6 @@ namespace Emby.Server.Implementations.Activity { /// /// The activity log entry point. - /// . /// public sealed class ActivityLogEntryPoint : IServerEntryPoint { diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs index 2d2dc8e61e..5c04c0e51a 100644 --- a/Emby.Server.Implementations/Activity/ActivityManager.cs +++ b/Emby.Server.Implementations/Activity/ActivityManager.cs @@ -6,7 +6,9 @@ using MediaBrowser.Model.Querying; namespace Emby.Server.Implementations.Activity { - /// + /// + /// The activity log manager. + /// public class ActivityManager : IActivityManager { /// diff --git a/Emby.Server.Implementations/Activity/ActivityRepository.cs b/Emby.Server.Implementations/Activity/ActivityRepository.cs index 697ad7fcc0..3aa1f03976 100644 --- a/Emby.Server.Implementations/Activity/ActivityRepository.cs +++ b/Emby.Server.Implementations/Activity/ActivityRepository.cs @@ -13,7 +13,9 @@ using SQLitePCL.pretty; namespace Emby.Server.Implementations.Activity { - /// + /// + /// The activity log repository. + /// public class ActivityRepository : BaseSqliteRepository, IActivityRepository { private static readonly CultureInfo _usCulture = CultureInfo.ReadOnly(new CultureInfo("en-US")); diff --git a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs index c677e9fbc3..3e149cc82c 100644 --- a/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs +++ b/Emby.Server.Implementations/Channels/ChannelDynamicMediaSourceProvider.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Controller.Channels; @@ -30,7 +31,7 @@ namespace Emby.Server.Implementations.Channels { return item.SourceType == SourceType.Channel ? _channelManager.GetDynamicMediaSources(item, cancellationToken) - : Task.FromResult>(new List()); + : Task.FromResult(Enumerable.Empty()); } /// diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 6e1baddfed..8beb5866f1 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -1,5 +1,3 @@ -#pragma warning disable CS1591 - using System; using System.Collections.Concurrent; using System.Collections.Generic; @@ -29,6 +27,9 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Channels { + /// + /// The LiveTV channel manager. + /// public class ChannelManager : IChannelManager { internal IChannel[] Channels { get; private set; } @@ -43,6 +44,18 @@ namespace Emby.Server.Implementations.Channels private readonly IJsonSerializer _jsonSerializer; private readonly IProviderManager _providerManager; + /// + /// Initializes a new instance of the class. + /// + /// The user manager. + /// The dto service. + /// The library manager. + /// The logger factory. + /// The server configuration manager. + /// The filesystem. + /// The user data manager. + /// The JSON serializer. + /// The provider manager. public ChannelManager( IUserManager userManager, IDtoService dtoService, @@ -67,11 +80,13 @@ namespace Emby.Server.Implementations.Channels private static TimeSpan CacheLength => TimeSpan.FromHours(3); + /// public void AddParts(IEnumerable channels) { Channels = channels.ToArray(); } + /// public bool EnableMediaSourceDisplay(BaseItem item) { var internalChannel = _libraryManager.GetItemById(item.ChannelId); @@ -80,15 +95,16 @@ namespace Emby.Server.Implementations.Channels return !(channel is IDisableMediaSourceDisplay); } + /// public bool CanDelete(BaseItem item) { var internalChannel = _libraryManager.GetItemById(item.ChannelId); var channel = Channels.FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(internalChannel.Id)); - var supportsDelete = channel as ISupportsDelete; - return supportsDelete != null && supportsDelete.CanDelete(item); + return channel is ISupportsDelete supportsDelete && supportsDelete.CanDelete(item); } + /// public bool EnableMediaProbe(BaseItem item) { var internalChannel = _libraryManager.GetItemById(item.ChannelId); @@ -97,6 +113,7 @@ namespace Emby.Server.Implementations.Channels return channel is ISupportsMediaProbe; } + /// public Task DeleteItem(BaseItem item) { var internalChannel = _libraryManager.GetItemById(item.ChannelId); @@ -123,11 +140,16 @@ namespace Emby.Server.Implementations.Channels .OrderBy(i => i.Name); } + /// + /// Returns an containing installed channel ID's. + /// + /// An containing installed channel ID's. public IEnumerable GetInstalledChannelIds() { return GetAllChannels().Select(i => GetInternalChannelId(i.Name)); } + /// public QueryResult GetChannelsInternal(ChannelQuery query) { var user = query.UserId.Equals(Guid.Empty) @@ -146,15 +168,13 @@ namespace Emby.Server.Implementations.Channels { try { - var hasAttributes = GetChannelProvider(i) as IHasFolderAttributes; - - return (hasAttributes != null && hasAttributes.Attributes.Contains("Recordings", StringComparer.OrdinalIgnoreCase)) == val; + return (GetChannelProvider(i) is IHasFolderAttributes hasAttributes + && hasAttributes.Attributes.Contains("Recordings", StringComparer.OrdinalIgnoreCase)) == val; } catch { return false; } - }).ToList(); } @@ -171,7 +191,6 @@ namespace Emby.Server.Implementations.Channels { return false; } - }).ToList(); } @@ -188,9 +207,9 @@ namespace Emby.Server.Implementations.Channels { return false; } - }).ToList(); } + if (query.IsFavorite.HasValue) { var val = query.IsFavorite.Value; @@ -215,7 +234,6 @@ namespace Emby.Server.Implementations.Channels { return false; } - }).ToList(); } @@ -226,6 +244,7 @@ namespace Emby.Server.Implementations.Channels { all = all.Skip(query.StartIndex.Value).ToList(); } + if (query.Limit.HasValue) { all = all.Take(query.Limit.Value).ToList(); @@ -248,6 +267,7 @@ namespace Emby.Server.Implementations.Channels }; } + /// public QueryResult GetChannels(ChannelQuery query) { var user = query.UserId.Equals(Guid.Empty) @@ -272,6 +292,12 @@ namespace Emby.Server.Implementations.Channels return result; } + /// + /// Refreshes the associated channels. + /// + /// The progress. + /// The cancellation token. + /// The completed task. public async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) { var allChannelsList = GetAllChannels().ToList(); @@ -305,14 +331,7 @@ namespace Emby.Server.Implementations.Channels private Channel GetChannelEntity(IChannel channel) { - var item = GetChannel(GetInternalChannelId(channel.Name)); - - if (item == null) - { - item = GetChannel(channel, CancellationToken.None).Result; - } - - return item; + return GetChannel(GetInternalChannelId(channel.Name)) ?? GetChannel(channel, CancellationToken.None).Result; } private List GetSavedMediaSources(BaseItem item) @@ -351,6 +370,7 @@ namespace Emby.Server.Implementations.Channels _jsonSerializer.SerializeToFile(mediaSources, path); } + /// public IEnumerable GetStaticMediaSources(BaseItem item, CancellationToken cancellationToken) { IEnumerable results = GetSavedMediaSources(item); @@ -360,6 +380,12 @@ namespace Emby.Server.Implementations.Channels .ToList(); } + /// + /// Gets the dynamic media sources based on the provided item. + /// + /// The item. + /// The cancellation token. + /// The completed task. public async Task> GetDynamicMediaSources(BaseItem item, CancellationToken cancellationToken) { var channel = GetChannel(item.ChannelId); @@ -409,7 +435,7 @@ namespace Emby.Server.Implementations.Channels private static MediaSourceInfo NormalizeMediaSource(BaseItem item, MediaSourceInfo info) { - info.RunTimeTicks = info.RunTimeTicks ?? item.RunTimeTicks; + info.RunTimeTicks ??= item.RunTimeTicks; return info; } @@ -482,41 +508,43 @@ namespace Emby.Server.Implementations.Channels private static string GetOfficialRating(ChannelParentalRating rating) { - switch (rating) - { - case ChannelParentalRating.Adult: - return "XXX"; - case ChannelParentalRating.UsR: - return "R"; - case ChannelParentalRating.UsPG13: - return "PG-13"; - case ChannelParentalRating.UsPG: - return "PG"; - default: - return null; - } + return rating switch + { + ChannelParentalRating.Adult => "XXX", + ChannelParentalRating.UsR => "R", + ChannelParentalRating.UsPG13 => "PG-13", + ChannelParentalRating.UsPG => "PG", + _ => null + }; } + /// + /// Gets a channel with the provided Guid. + /// + /// The Guid. + /// The corresponding channel. public Channel GetChannel(Guid id) { return _libraryManager.GetItemById(id) as Channel; } + /// public Channel GetChannel(string id) { return _libraryManager.GetItemById(id) as Channel; } + /// public ChannelFeatures[] GetAllChannelFeatures() { return _libraryManager.GetItemIds(new InternalItemsQuery { IncludeItemTypes = new[] { typeof(Channel).Name }, OrderBy = new[] { (ItemSortBy.SortName, SortOrder.Ascending) } - }).Select(i => GetChannelFeatures(i.ToString("N", CultureInfo.InvariantCulture))).ToArray(); } + /// public ChannelFeatures GetChannelFeatures(string id) { if (string.IsNullOrEmpty(id)) @@ -530,6 +558,11 @@ namespace Emby.Server.Implementations.Channels return GetChannelFeaturesDto(channel, channelProvider, channelProvider.GetChannelFeatures()); } + /// + /// Checks whether the provided Guid supports external transfer. + /// + /// The Guid. + /// Whether or not the provided Guid supports external transfer. public bool SupportsExternalTransfer(Guid channelId) { //var channel = GetChannel(channelId); @@ -538,6 +571,13 @@ namespace Emby.Server.Implementations.Channels return channelProvider.GetChannelFeatures().SupportsContentDownloading; } + /// + /// Gets the provided channel's supported features. + /// + /// The channel. + /// The provider. + /// The features. + /// The supported features. public ChannelFeatures GetChannelFeaturesDto(Channel channel, IChannel provider, InternalChannelFeatures features) @@ -570,6 +610,7 @@ namespace Emby.Server.Implementations.Channels return _libraryManager.GetNewItemId("Channel " + name, typeof(Channel)); } + /// public async Task> GetLatestChannelItems(InternalItemsQuery query, CancellationToken cancellationToken) { var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false); @@ -588,6 +629,7 @@ namespace Emby.Server.Implementations.Channels return result; } + /// public async Task> GetLatestChannelItemsInternal(InternalItemsQuery query, CancellationToken cancellationToken) { var channels = GetAllChannels().Where(i => i is ISupportsLatestMedia).ToArray(); @@ -662,6 +704,7 @@ namespace Emby.Server.Implementations.Channels } } + /// public async Task> GetChannelItemsInternal(InternalItemsQuery query, IProgress progress, CancellationToken cancellationToken) { // Get the internal channel entity @@ -711,7 +754,6 @@ namespace Emby.Server.Implementations.Channels { DeleteFileLocation = false, DeleteFromExternalProvider = false - }, parentItem, false); } } @@ -720,6 +762,7 @@ namespace Emby.Server.Implementations.Channels return _libraryManager.GetItemsResult(query); } + /// public async Task> GetChannelItems(InternalItemsQuery query, CancellationToken cancellationToken) { var internalResult = await GetChannelItemsInternal(query, new SimpleProgress(), cancellationToken).ConfigureAwait(false); @@ -743,7 +786,7 @@ namespace Emby.Server.Implementations.Channels bool sortDescending, CancellationToken cancellationToken) { - var userId = user == null ? null : user.Id.ToString("N", CultureInfo.InvariantCulture); + var userId = user?.Id.ToString("N", CultureInfo.InvariantCulture); var cacheLength = CacheLength; var cachePath = GetChannelDataCachePath(channel, userId, externalFolderId, sortField, sortDescending); @@ -794,7 +837,7 @@ namespace Emby.Server.Implementations.Channels var query = new InternalChannelItemQuery { - UserId = user == null ? Guid.Empty : user.Id, + UserId = user?.Id ?? Guid.Empty, SortBy = sortField, SortDescending = sortDescending, FolderId = externalFolderId @@ -843,8 +886,7 @@ namespace Emby.Server.Implementations.Channels var userCacheKey = string.Empty; - var hasCacheKey = channel as IHasCacheKey; - if (hasCacheKey != null) + if (channel is IHasCacheKey hasCacheKey) { userCacheKey = hasCacheKey.GetCacheKey(userId) ?? string.Empty; } @@ -919,59 +961,55 @@ namespace Emby.Server.Implementations.Channels if (info.Type == ChannelItemType.Folder) { - if (info.FolderType == ChannelFolderType.MusicAlbum) - { - item = GetItemById(info.Id, channelProvider.Name, out isNew); - } - else if (info.FolderType == ChannelFolderType.MusicArtist) + switch (info.FolderType) { - item = GetItemById(info.Id, channelProvider.Name, out isNew); - } - else if (info.FolderType == ChannelFolderType.PhotoAlbum) - { - item = GetItemById(info.Id, channelProvider.Name, out isNew); - } - else if (info.FolderType == ChannelFolderType.Series) - { - item = GetItemById(info.Id, channelProvider.Name, out isNew); - } - else if (info.FolderType == ChannelFolderType.Season) - { - item = GetItemById(info.Id, channelProvider.Name, out isNew); - } - else - { - item = GetItemById(info.Id, channelProvider.Name, out isNew); + case ChannelFolderType.MusicAlbum: + item = GetItemById(info.Id, channelProvider.Name, out isNew); + break; + case ChannelFolderType.MusicArtist: + item = GetItemById(info.Id, channelProvider.Name, out isNew); + break; + case ChannelFolderType.PhotoAlbum: + item = GetItemById(info.Id, channelProvider.Name, out isNew); + break; + case ChannelFolderType.Series: + item = GetItemById(info.Id, channelProvider.Name, out isNew); + break; + case ChannelFolderType.Season: + item = GetItemById(info.Id, channelProvider.Name, out isNew); + break; + default: + item = GetItemById(info.Id, channelProvider.Name, out isNew); + break; } } else if (info.MediaType == ChannelMediaType.Audio) { - if (info.ContentType == ChannelMediaContentType.Podcast) - { - item = GetItemById(info.Id, channelProvider.Name, out isNew); - } - else - { - item = GetItemById bool ListenWithHttps { get; } - /// - /// Gets a value indicating whether a client can connect to the server over HTTPS, either directly or via a - /// reverse proxy. - /// - bool CanConnectWithHttps { get; } - /// /// Gets a value indicating whether this instance has update available. /// From 00a0e013c695a3741218985afadd31265a6ddb40 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Thu, 16 Apr 2020 21:46:49 -0400 Subject: [PATCH 153/517] Update documentation for URL methods in ApplicationHost --- .../ApplicationHost.cs | 6 ++--- .../IServerApplicationHost.cs | 24 +++++++++++-------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index a39baa84ab..7699faf14e 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1510,7 +1510,7 @@ namespace Emby.Server.Implementations return GetLocalApiUrl(ipAddress.ToString()); } - /// + /// public string GetLocalApiUrl(ReadOnlySpan host) { var url = new StringBuilder(64); @@ -1559,7 +1559,7 @@ namespace Emby.Server.Implementations } } - var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); + var valid = await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); if (valid) { resultList.Add(address); @@ -1593,7 +1593,7 @@ namespace Emby.Server.Implementations private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private async Task IsIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken) + private async Task IsLocalIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken) { if (address.Equals(IPAddress.Loopback) || address.Equals(IPAddress.IPv6Loopback)) diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index d999f76dbf..8537e41800 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -56,29 +56,33 @@ namespace MediaBrowser.Controller string FriendlyName { get; } /// - /// Gets the local ip address. + /// Gets all the local IP addresses of this API instance. Each address is validated by sending a 'ping' request + /// to the API that should exist at the address. /// - /// The local ip address. + /// A cancellation token that can be used to cancel the task. + /// A list containing all the local IP addresses of the server. Task> GetLocalIpAddresses(CancellationToken cancellationToken); /// - /// Gets the local API URL. + /// Gets a local (LAN) URL that can be used to access the API. The hostname used is the first valid configured + /// IP address that can be found via . /// - /// The local API URL. + /// A cancellation token that can be used to cancel the task. + /// The server URL. Task GetLocalApiUrl(CancellationToken cancellationToken); /// - /// Gets the local API URL. + /// Gets a local (LAN) URL that can be used to access the API. /// - /// The hostname. - /// The local API URL. + /// The hostname to use in the URL. + /// The API URL. string GetLocalApiUrl(ReadOnlySpan hostname); /// - /// Gets the local API URL. + /// Gets a local (LAN) URL that can be used to access the API. /// - /// The IP address. - /// The local API URL. + /// The IP address to use as the hostname in the URL. + /// The API URL. string GetLocalApiUrl(IPAddress address); /// From 1666f3ca148c38609c85cb81e1e8b69e3473e319 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Thu, 16 Apr 2020 23:40:32 -0400 Subject: [PATCH 154/517] Use dependency injection to construct migration routines --- .../Migrations/IMigrationRoutine.cs | 4 +--- Jellyfin.Server/Migrations/MigrationRunner.cs | 19 ++++++++++++------- .../Routines/CreateUserLoggingConfigFile.cs | 11 +++++++++-- .../Routines/DisableTranscodingThrottling.cs | 17 +++++++++++++---- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Jellyfin.Server/Migrations/IMigrationRoutine.cs b/Jellyfin.Server/Migrations/IMigrationRoutine.cs index eab995d67e..b79fdeac03 100644 --- a/Jellyfin.Server/Migrations/IMigrationRoutine.cs +++ b/Jellyfin.Server/Migrations/IMigrationRoutine.cs @@ -21,8 +21,6 @@ namespace Jellyfin.Server.Migrations /// /// Execute the migration routine. /// - /// Host that hosts current version. - /// Host logger. - public void Perform(CoreAppHost host, ILogger logger); + public void Perform(); } } diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index b5ea04dcac..ca17482820 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using MediaBrowser.Common.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Jellyfin.Server.Migrations @@ -13,10 +14,10 @@ namespace Jellyfin.Server.Migrations /// /// The list of known migrations, in order of applicability. /// - internal static readonly IMigrationRoutine[] Migrations = + private static readonly Type[] _migrationTypes = { - new Routines.DisableTranscodingThrottling(), - new Routines.CreateUserLoggingConfigFile() + typeof(Routines.DisableTranscodingThrottling), + typeof(Routines.CreateUserLoggingConfigFile) }; /// @@ -27,6 +28,10 @@ namespace Jellyfin.Server.Migrations public static void Run(CoreAppHost host, ILoggerFactory loggerFactory) { var logger = loggerFactory.CreateLogger(); + var migrations = _migrationTypes + .Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m)) + .OfType() + .ToArray(); var migrationOptions = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration(MigrationsListStore.StoreKey); if (!host.ServerConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0) @@ -34,16 +39,16 @@ namespace Jellyfin.Server.Migrations // If startup wizard is not finished, this is a fresh install. // Don't run any migrations, just mark all of them as applied. logger.LogInformation("Marking all known migrations as applied because this is a fresh install"); - migrationOptions.Applied.AddRange(Migrations.Select(m => (m.Id, m.Name))); + migrationOptions.Applied.AddRange(migrations.Select(m => (m.Id, m.Name))); host.ServerConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions); return; } var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet(); - for (var i = 0; i < Migrations.Length; i++) + for (var i = 0; i < migrations.Length; i++) { - var migrationRoutine = Migrations[i]; + var migrationRoutine = migrations[i]; if (appliedMigrationIds.Contains(migrationRoutine.Id)) { logger.LogDebug("Skipping migration '{Name}' since it is already applied", migrationRoutine.Name); @@ -54,7 +59,7 @@ namespace Jellyfin.Server.Migrations try { - migrationRoutine.Perform(host, logger); + migrationRoutine.Perform(); } catch (Exception ex) { diff --git a/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs b/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs index 3bc32c0478..89514c89b7 100644 --- a/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs +++ b/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs @@ -36,6 +36,13 @@ namespace Jellyfin.Server.Migrations.Routines @"{""Serilog"":{""MinimumLevel"":""Information"",""WriteTo"":[{""Name"":""Console"",""Args"":{""outputTemplate"":""[{Timestamp:HH:mm:ss}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}""}},{""Name"":""Async"",""Args"":{""configure"":[{""Name"":""File"",""Args"":{""path"":""%JELLYFIN_LOG_DIR%//log_.log"",""rollingInterval"":""Day"",""retainedFileCountLimit"":3,""rollOnFileSizeLimit"":true,""fileSizeLimitBytes"":100000000,""outputTemplate"":""[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}:{Message}{NewLine}{Exception}""}}]}}],""Enrich"":[""FromLogContext"",""WithThreadId""]}}", }; + private readonly IApplicationPaths _appPaths; + + public CreateUserLoggingConfigFile(IApplicationPaths appPaths) + { + _appPaths = appPaths; + } + /// public Guid Id => Guid.Parse("{EF103419-8451-40D8-9F34-D1A8E93A1679}"); @@ -43,9 +50,9 @@ namespace Jellyfin.Server.Migrations.Routines public string Name => "CreateLoggingConfigHeirarchy"; /// - public void Perform(CoreAppHost host, ILogger logger) + public void Perform() { - var logDirectory = host.Resolve().ConfigurationDirectoryPath; + var logDirectory = _appPaths.ConfigurationDirectoryPath; var existingConfigPath = Path.Combine(logDirectory, "logging.json"); // If the existing logging.json config file is unmodified, then 'reset' it by moving it to 'logging.old.json' diff --git a/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs b/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs index 6f8e4a8ffb..b2e957d5bb 100644 --- a/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs +++ b/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs @@ -10,6 +10,15 @@ namespace Jellyfin.Server.Migrations.Routines /// internal class DisableTranscodingThrottling : IMigrationRoutine { + private readonly ILogger _logger; + private readonly IConfigurationManager _configManager; + + public DisableTranscodingThrottling(ILogger logger, IConfigurationManager configManager) + { + _logger = logger; + _configManager = configManager; + } + /// public Guid Id => Guid.Parse("{4124C2CD-E939-4FFB-9BE9-9B311C413638}"); @@ -17,16 +26,16 @@ namespace Jellyfin.Server.Migrations.Routines public string Name => "DisableTranscodingThrottling"; /// - public void Perform(CoreAppHost host, ILogger logger) + public void Perform() { // Set EnableThrottling to false since it wasn't used before and may introduce issues - var encoding = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration("encoding"); + var encoding = _configManager.GetConfiguration("encoding"); if (encoding.EnableThrottling) { - logger.LogInformation("Disabling transcoding throttling during migration"); + _logger.LogInformation("Disabling transcoding throttling during migration"); encoding.EnableThrottling = false; - host.ServerConfigurationManager.SaveConfiguration("encoding", encoding); + _configManager.SaveConfiguration("encoding", encoding); } } } From ecf49caf0d1392b0f2aa83bce1d08a006463566d Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 17 Apr 2020 10:24:46 -0400 Subject: [PATCH 155/517] Add back warning message when Skia encoder cannot be used --- Jellyfin.Server/CoreAppHost.cs | 11 ++++++++++- .../MediaEncoding/EncodingHelper.cs | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index 0769bf844e..f678e714c1 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Reflection; using Emby.Drawing; @@ -42,11 +43,19 @@ namespace Jellyfin.Server /// protected override void RegisterServices(IServiceCollection serviceCollection) { - var imageEncoderType = SkiaEncoder.IsNativeLibAvailable() + // Register an image encoder + bool useSkiaEncoder = SkiaEncoder.IsNativeLibAvailable(); + Type imageEncoderType = useSkiaEncoder ? typeof(SkiaEncoder) : typeof(NullImageEncoder); serviceCollection.AddSingleton(typeof(IImageEncoder), imageEncoderType); + // Log a warning if the Skia encoder could not be used + if (!useSkiaEncoder) + { + Logger.LogWarning($"Skia not available. Will fallback to {nameof(NullImageEncoder)}."); + } + base.RegisterServices(serviceCollection); } diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 3552a45a23..5efb10d3a9 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -459,7 +459,7 @@ namespace MediaBrowser.Controller.MediaEncoding { var videoDecoder = GetHardwareAcceleratedVideoDecoder(state, encodingOptions); var outputVideoCodec = GetVideoEncoder(state, encodingOptions); - + var hasTextSubs = state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && state.SubtitleDeliveryMethod == SubtitleDeliveryMethod.Encode; if (!hasTextSubs) From 0bef4eef872c39fc9f747db7648b86f475c4a643 Mon Sep 17 00:00:00 2001 From: randrey Date: Fri, 17 Apr 2020 14:45:56 -0700 Subject: [PATCH 156/517] Fix InvalidOperationException while browsing via DLNA client. --- Emby.Dlna/Didl/DidlBuilder.cs | 102 ++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 30 deletions(-) diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index 88cc00e30a..f9e9de8ff2 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -425,57 +425,99 @@ namespace Emby.Dlna.Didl } } - if (item is Episode episode && context is Season season) + return item is Episode episode + ? GetEpisodeDisplayName(episode, context) + : item.Name; + } + + /// + /// Gets episode display name appropriate for the given context. + /// + /// + /// If context is a season, this will return a string containing just episode number and name. + /// Otherwise the result will include series nams and season number. + /// + /// The episode. + /// Current context. + /// Formatted name of the episode. + private string GetEpisodeDisplayName(Episode episode, BaseItem context) + { + string[] components; + + if (context is Season season) { // This is a special embedded within a season - if (item.ParentIndexNumber.HasValue && item.ParentIndexNumber.Value == 0 + if (episode.ParentIndexNumber.HasValue && episode.ParentIndexNumber.Value == 0 && season.IndexNumber.HasValue && season.IndexNumber.Value != 0) { return string.Format( CultureInfo.InvariantCulture, _localization.GetLocalizedString("ValueSpecialEpisodeName"), - item.Name); + episode.Name); } - if (item.IndexNumber.HasValue) - { - var number = item.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); + // inside a season use simple format (ex. '12 - Episode Name') + var epNumberName = GetEpisodeIndexFullName(episode); + components = new[] { epNumberName, episode.Name }; + } + else + { + // outside a season include series and season details (ex. 'TV Show - S05E11 - Episode Name') + var epNumberName = GetEpisodeNumberDisplayName(episode); + components = new[] { episode.SeriesName, epNumberName, episode.Name }; + } - if (episode.IndexNumberEnd.HasValue) - { - number += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture); - } + return string.Join(" - ", components.Where(NotNullOrWhiteSpace)); + } - return number + " - " + item.Name; - } - } - else if (item is Episode ep) + /// + /// Gets complete episode number. + /// + /// The episode. + /// For single episodes returns just the number. For double episodes - current and ending numbers. + private string GetEpisodeIndexFullName(Episode episode) + { + var name = string.Empty; + if (episode.IndexNumber.HasValue) { - var parent = ep.GetParent(); - var name = parent.Name + " - "; + name += episode.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); - if (ep.ParentIndexNumber.HasValue) - { - name += "S" + ep.ParentIndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); - } - else if (!item.IndexNumber.HasValue) + if (episode.IndexNumberEnd.HasValue) { - return name + " - " + item.Name; + name += "-" + episode.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture); } + } - name += "E" + ep.IndexNumber.Value.ToString("00", CultureInfo.InvariantCulture); - if (ep.IndexNumberEnd.HasValue) - { - name += "-" + ep.IndexNumberEnd.Value.ToString("00", CultureInfo.InvariantCulture); - } + return name; + } - name += " - " + item.Name; - return name; + /// + /// Gets episode number formatted as 'S##E##'. + /// + /// The episode. + /// Formatted episode number. + private string GetEpisodeNumberDisplayName(Episode episode) + { + var name = string.Empty; + var seasonNumber = episode.Season?.IndexNumber; + + if (seasonNumber.HasValue) + { + name = "S" + seasonNumber.Value.ToString("00", CultureInfo.InvariantCulture); + } + + var indexName = GetEpisodeIndexFullName(episode); + + if (!string.IsNullOrWhiteSpace(indexName)) + { + name += "E" + indexName; } - return item.Name; + return name; } + private bool NotNullOrWhiteSpace(string s) => !string.IsNullOrWhiteSpace(s); + private void AddAudioResource(XmlWriter writer, BaseItem audio, string deviceId, Filter filter, StreamInfo streamInfo = null) { writer.WriteStartElement(string.Empty, "res", NS_DIDL); From d99536e99fe7e8d204ef93db39e519afbbfdad0a Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 19 Apr 2020 11:57:03 +0200 Subject: [PATCH 157/517] Improved tests --- Emby.Naming/Audio/AlbumParser.cs | 15 ++-- Emby.Naming/Audio/AudioFileParser.cs | 3 +- Emby.Naming/Common/EpisodeExpression.cs | 7 +- Emby.Naming/Subtitles/SubtitleParser.cs | 12 +-- .../Music/MultiDiscAlbumTests.cs | 88 ++++++++----------- .../Subtitles/SubtitleParserTests.cs | 49 ++++++----- 6 files changed, 80 insertions(+), 94 deletions(-) diff --git a/Emby.Naming/Audio/AlbumParser.cs b/Emby.Naming/Audio/AlbumParser.cs index 33f4468d9f..23ff8c3fa2 100644 --- a/Emby.Naming/Audio/AlbumParser.cs +++ b/Emby.Naming/Audio/AlbumParser.cs @@ -1,3 +1,4 @@ +#nullable enable #pragma warning disable CS1591 using System; @@ -22,7 +23,7 @@ namespace Emby.Naming.Audio { var filename = Path.GetFileName(path); - if (string.IsNullOrEmpty(filename)) + if (path.Length == 0) { return false; } @@ -39,18 +40,22 @@ namespace Emby.Naming.Audio filename = filename.Replace(')', ' '); filename = Regex.Replace(filename, @"\s+", " "); - filename = filename.TrimStart(); + ReadOnlySpan trimmedFilename = filename.TrimStart(); foreach (var prefix in _options.AlbumStackingPrefixes) { - if (filename.IndexOf(prefix, StringComparison.OrdinalIgnoreCase) != 0) + if (!trimmedFilename.StartsWith(prefix, StringComparison.OrdinalIgnoreCase)) { continue; } - var tmp = filename.Substring(prefix.Length); + var tmp = trimmedFilename.Slice(prefix.Length).Trim(); - tmp = tmp.Trim().Split(' ').FirstOrDefault() ?? string.Empty; + int index = tmp.IndexOf(' '); + if (index != -1) + { + tmp = tmp.Slice(0, index); + } if (int.TryParse(tmp, NumberStyles.Integer, CultureInfo.InvariantCulture, out _)) { diff --git a/Emby.Naming/Audio/AudioFileParser.cs b/Emby.Naming/Audio/AudioFileParser.cs index 25d5f8735e..6b2f4be93e 100644 --- a/Emby.Naming/Audio/AudioFileParser.cs +++ b/Emby.Naming/Audio/AudioFileParser.cs @@ -1,3 +1,4 @@ +#nullable enable #pragma warning disable CS1591 using System; @@ -11,7 +12,7 @@ namespace Emby.Naming.Audio { public static bool IsAudioFile(string path, NamingOptions options) { - var extension = Path.GetExtension(path) ?? string.Empty; + var extension = Path.GetExtension(path); return options.AudioFileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase); } } diff --git a/Emby.Naming/Common/EpisodeExpression.cs b/Emby.Naming/Common/EpisodeExpression.cs index 07de728514..ed6ba8881c 100644 --- a/Emby.Naming/Common/EpisodeExpression.cs +++ b/Emby.Naming/Common/EpisodeExpression.cs @@ -23,11 +23,6 @@ namespace Emby.Naming.Common { } - public EpisodeExpression() - : this(null) - { - } - public string Expression { get => _expression; @@ -48,6 +43,6 @@ namespace Emby.Naming.Common public string[] DateTimeFormats { get; set; } - public Regex Regex => _regex ?? (_regex = new Regex(Expression, RegexOptions.IgnoreCase | RegexOptions.Compiled)); + public Regex Regex => _regex ??= new Regex(Expression, RegexOptions.IgnoreCase | RegexOptions.Compiled); } } diff --git a/Emby.Naming/Subtitles/SubtitleParser.cs b/Emby.Naming/Subtitles/SubtitleParser.cs index 88ec3e2d60..542584bee9 100644 --- a/Emby.Naming/Subtitles/SubtitleParser.cs +++ b/Emby.Naming/Subtitles/SubtitleParser.cs @@ -1,3 +1,4 @@ +#nullable enable #pragma warning disable CS1591 using System; @@ -16,11 +17,11 @@ namespace Emby.Naming.Subtitles _options = options; } - public SubtitleInfo ParseFile(string path) + public SubtitleInfo? ParseFile(string path) { - if (string.IsNullOrEmpty(path)) + if (path.Length == 0) { - throw new ArgumentNullException(nameof(path)); + throw new ArgumentException("String can't be empty.", nameof(path)); } var extension = Path.GetExtension(path); @@ -52,11 +53,6 @@ namespace Emby.Naming.Subtitles private string[] GetFlags(string path) { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException(nameof(path)); - } - // Note: the tags need be be surrounded be either a space ( ), hyphen -, dot . or underscore _. var file = Path.GetFileName(path); diff --git a/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs b/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs index 9a4b0b5422..45d5df09af 100644 --- a/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs +++ b/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs @@ -6,61 +6,43 @@ namespace Jellyfin.Naming.Tests.Music { public class MultiDiscAlbumTests { - [Fact] - public void TestMultiDiscAlbums() + private readonly NamingOptions _namingOptions = new NamingOptions(); + + [Theory] + [InlineData("", false)] + [InlineData(@"blah blah", false)] + [InlineData(@"D:/music/weezer/03 Pinkerton", false)] + [InlineData(@"D:/music/michael jackson/Bad (2012 Remaster)", false)] + [InlineData(@"cd1", true)] + [InlineData(@"disc18", true)] + [InlineData(@"disk10", true)] + [InlineData(@"vol7", true)] + [InlineData(@"volume1", true)] + [InlineData(@"cd 1", true)] + [InlineData(@"disc 1", true)] + [InlineData(@"disk 1", true)] + [InlineData(@"disk", false)] + [InlineData(@"disk ·", false)] + [InlineData(@"disk a", false)] + [InlineData(@"disk volume", false)] + [InlineData(@"disc disc", false)] + [InlineData(@"disk disc 6", false)] + [InlineData(@"cd - 1", true)] + [InlineData(@"disc- 1", true)] + [InlineData(@"disk - 1", true)] + [InlineData(@"Disc 01 (Hugo Wolf · 24 Lieder)", true)] + [InlineData(@"Disc 04 (Encores and Folk Songs)", true)] + [InlineData(@"Disc04 (Encores and Folk Songs)", true)] + [InlineData(@"Disc 04(Encores and Folk Songs)", true)] + [InlineData(@"Disc04(Encores and Folk Songs)", true)] + [InlineData(@"D:/Video/MBTestLibrary/VideoTest/music/.38 special/anth/Disc 2", true)] + [InlineData(@"[1985] Opportunities (Let's make lots of money) (1985)", false)] + [InlineData(@"Blah 04(Encores and Folk Songs)", false)] + public void TestMultiDiscAlbums(string path, bool result) { - Assert.False(IsMultiDiscAlbumFolder(@"blah blah")); - Assert.False(IsMultiDiscAlbumFolder(@"D:/music/weezer/03 Pinkerton")); - Assert.False(IsMultiDiscAlbumFolder(@"D:/music/michael jackson/Bad (2012 Remaster)")); + var parser = new AlbumParser(_namingOptions); - Assert.True(IsMultiDiscAlbumFolder(@"cd1")); - Assert.True(IsMultiDiscAlbumFolder(@"disc18")); - Assert.True(IsMultiDiscAlbumFolder(@"disk10")); - Assert.True(IsMultiDiscAlbumFolder(@"vol7")); - Assert.True(IsMultiDiscAlbumFolder(@"volume1")); - - Assert.True(IsMultiDiscAlbumFolder(@"cd 1")); - Assert.True(IsMultiDiscAlbumFolder(@"disc 1")); - Assert.True(IsMultiDiscAlbumFolder(@"disk 1")); - - Assert.False(IsMultiDiscAlbumFolder(@"disk")); - Assert.False(IsMultiDiscAlbumFolder(@"disk ·")); - Assert.False(IsMultiDiscAlbumFolder(@"disk a")); - - Assert.False(IsMultiDiscAlbumFolder(@"disk volume")); - Assert.False(IsMultiDiscAlbumFolder(@"disc disc")); - Assert.False(IsMultiDiscAlbumFolder(@"disk disc 6")); - - Assert.True(IsMultiDiscAlbumFolder(@"cd - 1")); - Assert.True(IsMultiDiscAlbumFolder(@"disc- 1")); - Assert.True(IsMultiDiscAlbumFolder(@"disk - 1")); - - Assert.True(IsMultiDiscAlbumFolder(@"Disc 01 (Hugo Wolf · 24 Lieder)")); - Assert.True(IsMultiDiscAlbumFolder(@"Disc 04 (Encores and Folk Songs)")); - Assert.True(IsMultiDiscAlbumFolder(@"Disc04 (Encores and Folk Songs)")); - Assert.True(IsMultiDiscAlbumFolder(@"Disc 04(Encores and Folk Songs)")); - Assert.True(IsMultiDiscAlbumFolder(@"Disc04(Encores and Folk Songs)")); - - Assert.True(IsMultiDiscAlbumFolder(@"D:/Video/MBTestLibrary/VideoTest/music/.38 special/anth/Disc 2")); - } - - [Fact] - public void TestMultiDiscAlbums1() - { - Assert.False(IsMultiDiscAlbumFolder(@"[1985] Opportunities (Let's make lots of money) (1985)")); - } - - [Fact] - public void TestMultiDiscAlbums2() - { - Assert.False(IsMultiDiscAlbumFolder(@"Blah 04(Encores and Folk Songs)")); - } - - private bool IsMultiDiscAlbumFolder(string path) - { - var parser = new AlbumParser(new NamingOptions()); - - return parser.IsMultiPart(path); + Assert.Equal(result, parser.IsMultiPart(path)); } } } diff --git a/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs b/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs index 41da889c28..8b9425e8e0 100644 --- a/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs +++ b/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs @@ -1,4 +1,5 @@ -using Emby.Naming.Common; +using System; +using Emby.Naming.Common; using Emby.Naming.Subtitles; using Xunit; @@ -6,28 +7,19 @@ namespace Jellyfin.Naming.Tests.Subtitles { public class SubtitleParserTests { - private SubtitleParser GetParser() - { - var options = new NamingOptions(); - - return new SubtitleParser(options); - } - - [Fact] - public void TestSubtitles() - { - Test("The Skin I Live In (2011).srt", null, false, false); - Test("The Skin I Live In (2011).eng.srt", "eng", false, false); - Test("The Skin I Live In (2011).eng.default.srt", "eng", true, false); - Test("The Skin I Live In (2011).eng.forced.srt", "eng", false, true); - Test("The Skin I Live In (2011).eng.foreign.srt", "eng", false, true); - Test("The Skin I Live In (2011).eng.default.foreign.srt", "eng", true, true); - Test("The Skin I Live In (2011).default.foreign.eng.srt", "eng", true, true); - } + private readonly NamingOptions _namingOptions = new NamingOptions(); - private void Test(string input, string language, bool isDefault, bool isForced) + [Theory] + [InlineData("The Skin I Live In (2011).srt", null, false, false)] + [InlineData("The Skin I Live In (2011).eng.srt", "eng", false, false)] + [InlineData("The Skin I Live In (2011).eng.default.srt", "eng", true, false)] + [InlineData("The Skin I Live In (2011).eng.forced.srt", "eng", false, true)] + [InlineData("The Skin I Live In (2011).eng.foreign.srt", "eng", false, true)] + [InlineData("The Skin I Live In (2011).eng.default.foreign.srt", "eng", true, true)] + [InlineData("The Skin I Live In (2011).default.foreign.eng.srt", "eng", true, true)] + public void TestSubtitles(string input, string language, bool isDefault, bool isForced) { - var parser = GetParser(); + var parser = new SubtitleParser(_namingOptions); var result = parser.ParseFile(input); @@ -35,5 +27,20 @@ namespace Jellyfin.Naming.Tests.Subtitles Assert.Equal(isDefault, result.IsDefault); Assert.Equal(isForced, result.IsForced); } + + [Theory] + [InlineData("The Skin I Live In (2011).mp4")] + public void TestNonSubtitles(string input) + { + var parser = new SubtitleParser(_namingOptions); + + Assert.Null(parser.ParseFile(input)); + } + + [Fact] + public void TestEmptySubtitlesPath() + { + Assert.Throws(() => new SubtitleParser(_namingOptions).ParseFile(string.Empty)); + } } } From fc3e2baccc8c32171df655043feb7afae6bab34c Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sun, 19 Apr 2020 18:27:07 +0200 Subject: [PATCH 158/517] Address comments --- Emby.Naming/Audio/AlbumParser.cs | 4 +--- Emby.Naming/Subtitles/SubtitleParser.cs | 2 +- .../Extensions/StringHelperTests.cs | 19 +++++++++++++++++ .../Jellyfin.Model.Tests.csproj | 21 +++++++++++++++++++ .../Music/MultiDiscAlbumTests.cs | 4 +++- .../Subtitles/SubtitleParserTests.cs | 6 +++--- 6 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 tests/Jellyfin.Model.Tests/Extensions/StringHelperTests.cs create mode 100644 tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj diff --git a/Emby.Naming/Audio/AlbumParser.cs b/Emby.Naming/Audio/AlbumParser.cs index 23ff8c3fa2..b63be3a647 100644 --- a/Emby.Naming/Audio/AlbumParser.cs +++ b/Emby.Naming/Audio/AlbumParser.cs @@ -4,7 +4,6 @@ using System; using System.Globalization; using System.IO; -using System.Linq; using System.Text.RegularExpressions; using Emby.Naming.Common; @@ -22,8 +21,7 @@ namespace Emby.Naming.Audio public bool IsMultiPart(string path) { var filename = Path.GetFileName(path); - - if (path.Length == 0) + if (filename.Length == 0) { return false; } diff --git a/Emby.Naming/Subtitles/SubtitleParser.cs b/Emby.Naming/Subtitles/SubtitleParser.cs index 542584bee9..24e59f90a3 100644 --- a/Emby.Naming/Subtitles/SubtitleParser.cs +++ b/Emby.Naming/Subtitles/SubtitleParser.cs @@ -21,7 +21,7 @@ namespace Emby.Naming.Subtitles { if (path.Length == 0) { - throw new ArgumentException("String can't be empty.", nameof(path)); + throw new ArgumentException("File path can't be empty.", nameof(path)); } var extension = Path.GetExtension(path); diff --git a/tests/Jellyfin.Model.Tests/Extensions/StringHelperTests.cs b/tests/Jellyfin.Model.Tests/Extensions/StringHelperTests.cs new file mode 100644 index 0000000000..d68cf0f7c0 --- /dev/null +++ b/tests/Jellyfin.Model.Tests/Extensions/StringHelperTests.cs @@ -0,0 +1,19 @@ +using System; +using MediaBrowser.Model.Extensions; +using Xunit; + +namespace Jellyfin.Model.Tests.Extensions +{ + public class StringHelperTests + { + [Theory] + [InlineData("", "")] + [InlineData("banana", "Banana")] + [InlineData("Banana", "Banana")] + [InlineData("ä", "Ä")] + public void FirstToUpperTest(string str, string result) + { + Assert.Equal(result, StringHelper.FirstToUpper(str)); + } + } +} diff --git a/tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj b/tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj new file mode 100644 index 0000000000..f6c3274986 --- /dev/null +++ b/tests/Jellyfin.Model.Tests/Jellyfin.Model.Tests.csproj @@ -0,0 +1,21 @@ + + + + netcoreapp3.1 + false + true + enable + + + + + + + + + + + + + + diff --git a/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs b/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs index 45d5df09af..c9a295a4ce 100644 --- a/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs +++ b/tests/Jellyfin.Naming.Tests/Music/MultiDiscAlbumTests.cs @@ -10,6 +10,8 @@ namespace Jellyfin.Naming.Tests.Music [Theory] [InlineData("", false)] + [InlineData("C:/", false)] + [InlineData("/home/", false)] [InlineData(@"blah blah", false)] [InlineData(@"D:/music/weezer/03 Pinkerton", false)] [InlineData(@"D:/music/michael jackson/Bad (2012 Remaster)", false)] @@ -38,7 +40,7 @@ namespace Jellyfin.Naming.Tests.Music [InlineData(@"D:/Video/MBTestLibrary/VideoTest/music/.38 special/anth/Disc 2", true)] [InlineData(@"[1985] Opportunities (Let's make lots of money) (1985)", false)] [InlineData(@"Blah 04(Encores and Folk Songs)", false)] - public void TestMultiDiscAlbums(string path, bool result) + public void AlbumParser_MultidiscPath_Identifies(string path, bool result) { var parser = new AlbumParser(_namingOptions); diff --git a/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs b/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs index 8b9425e8e0..a438318ca7 100644 --- a/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs +++ b/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs @@ -17,7 +17,7 @@ namespace Jellyfin.Naming.Tests.Subtitles [InlineData("The Skin I Live In (2011).eng.foreign.srt", "eng", false, true)] [InlineData("The Skin I Live In (2011).eng.default.foreign.srt", "eng", true, true)] [InlineData("The Skin I Live In (2011).default.foreign.eng.srt", "eng", true, true)] - public void TestSubtitles(string input, string language, bool isDefault, bool isForced) + public void SubtitleParser_ValidFileNames_Parses(string input, string language, bool isDefault, bool isForced) { var parser = new SubtitleParser(_namingOptions); @@ -30,7 +30,7 @@ namespace Jellyfin.Naming.Tests.Subtitles [Theory] [InlineData("The Skin I Live In (2011).mp4")] - public void TestNonSubtitles(string input) + public void SubtitleParser_InvalidFileNames_ReturnsNull(string input) { var parser = new SubtitleParser(_namingOptions); @@ -38,7 +38,7 @@ namespace Jellyfin.Naming.Tests.Subtitles } [Fact] - public void TestEmptySubtitlesPath() + public void SubtitleParser_EmptyFileNames_ThrowsArgumentException() { Assert.Throws(() => new SubtitleParser(_namingOptions).ParseFile(string.Empty)); } From f26f44acaf86bb35ff1d2be7cb37a57dee7a47cf Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sun, 19 Apr 2020 13:39:12 -0400 Subject: [PATCH 159/517] Apply code review suggestions --- .../Branding/BrandingConfigurationFactory.cs | 2 +- .../Channels/ChannelManager.cs | 67 ++++++------------- .../Channels/ChannelPostScanTask.cs | 3 +- 3 files changed, 24 insertions(+), 48 deletions(-) diff --git a/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs b/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs index 43c8cd5fa2..7ae26bd8b4 100644 --- a/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs +++ b/Emby.Server.Implementations/Branding/BrandingConfigurationFactory.cs @@ -5,7 +5,7 @@ using MediaBrowser.Model.Branding; namespace Emby.Server.Implementations.Branding { /// - /// Branding configuration factory. + /// A configuration factory for . /// public class BrandingConfigurationFactory : IConfigurationFactory { diff --git a/Emby.Server.Implementations/Channels/ChannelManager.cs b/Emby.Server.Implementations/Channels/ChannelManager.cs index 8beb5866f1..41eb58bab0 100644 --- a/Emby.Server.Implementations/Channels/ChannelManager.cs +++ b/Emby.Server.Implementations/Channels/ChannelManager.cs @@ -141,9 +141,9 @@ namespace Emby.Server.Implementations.Channels } /// - /// Returns an containing installed channel ID's. + /// Get the installed channel IDs. /// - /// An containing installed channel ID's. + /// An containing installed channel IDs. public IEnumerable GetInstalledChannelIds() { return GetAllChannels().Select(i => GetInternalChannelId(i.Name)); @@ -296,7 +296,7 @@ namespace Emby.Server.Implementations.Channels /// Refreshes the associated channels. /// /// The progress. - /// The cancellation token. + /// A cancellation token that can be used to cancel the operation. /// The completed task. public async Task RefreshChannels(IProgress progress, CancellationToken cancellationToken) { @@ -384,8 +384,8 @@ namespace Emby.Server.Implementations.Channels /// Gets the dynamic media sources based on the provided item. /// /// The item. - /// The cancellation token. - /// The completed task. + /// A cancellation token that can be used to cancel the operation. + /// The task representing the operation to get the media sources. public async Task> GetDynamicMediaSources(BaseItem item, CancellationToken cancellationToken) { var channel = GetChannel(item.ChannelId); @@ -578,7 +578,8 @@ namespace Emby.Server.Implementations.Channels /// The provider. /// The features. /// The supported features. - public ChannelFeatures GetChannelFeaturesDto(Channel channel, + public ChannelFeatures GetChannelFeaturesDto( + Channel channel, IChannel provider, InternalChannelFeatures features) { @@ -961,27 +962,15 @@ namespace Emby.Server.Implementations.Channels if (info.Type == ChannelItemType.Folder) { - switch (info.FolderType) + item = info.FolderType switch { - case ChannelFolderType.MusicAlbum: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - case ChannelFolderType.MusicArtist: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - case ChannelFolderType.PhotoAlbum: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - case ChannelFolderType.Series: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - case ChannelFolderType.Season: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - default: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - } + ChannelFolderType.MusicAlbum => GetItemById(info.Id, channelProvider.Name, out isNew), + ChannelFolderType.MusicArtist => GetItemById(info.Id, channelProvider.Name, out isNew), + ChannelFolderType.PhotoAlbum => GetItemById(info.Id, channelProvider.Name, out isNew), + ChannelFolderType.Series => GetItemById(info.Id, channelProvider.Name, out isNew), + ChannelFolderType.Season => GetItemById(info.Id, channelProvider.Name, out isNew), + _ => GetItemById(info.Id, channelProvider.Name, out isNew) + }; } else if (info.MediaType == ChannelMediaType.Audio) { @@ -991,26 +980,14 @@ namespace Emby.Server.Implementations.Channels } else { - switch (info.ContentType) + item = info.ContentType switch { - case ChannelMediaContentType.Episode: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - case ChannelMediaContentType.Movie: - item = GetItemById(info.Id, channelProvider.Name, out isNew); - break; - default: - if (info.ContentType == ChannelMediaContentType.Trailer || info.ExtraType == ExtraType.Trailer) - { - item = GetItemById(info.Id, channelProvider.Name, out isNew); - } - else - { - item = GetItemById