From 976459d3e8a8b889cebc2cf281e38b0fbc19c9b9 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Tue, 17 Dec 2019 23:15:02 +0100 Subject: [PATCH 0001/1003] 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 0002/1003] 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 0003/1003] 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 0004/1003] 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 0005/1003] 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 0006/1003] 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 0007/1003] 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 0008/1003] 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 0009/1003] 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 974a04c12939068b23b62ee6ebb1e7fc2e830eec Mon Sep 17 00:00:00 2001 From: dkanada Date: Wed, 26 Feb 2020 01:58:39 +0900 Subject: [PATCH 0010/1003] update plugin classes for nightly builds --- .../Activity/ActivityLogEntryPoint.cs | 8 +- .../ApplicationHost.cs | 10 +- .../Updates/InstallationManager.cs | 68 +++++------ MediaBrowser.Api/PackageService.cs | 36 +----- .../Extensions/BaseExtensions.cs | 1 - MediaBrowser.Common/IApplicationHost.cs | 4 +- MediaBrowser.Common/Plugins/BasePlugin.cs | 8 +- .../Updates/IInstallationManager.cs | 22 ++-- .../Updates/InstallationEventArgs.cs | 2 +- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 +- MediaBrowser.Model/System/SystemInfo.cs | 2 +- .../Updates/CheckForUpdateResult.cs | 4 +- .../Updates/InstallationInfo.cs | 2 +- MediaBrowser.Model/Updates/PackageInfo.cs | 106 +----------------- .../Updates/PackageTargetSystem.cs | 23 ---- .../Updates/PackageVersionInfo.cs | 97 ---------------- ...ckageVersionClass.cs => ReleaseChannel.cs} | 15 +-- MediaBrowser.Model/Updates/VersionInfo.cs | 73 ++++++++++++ 18 files changed, 150 insertions(+), 333 deletions(-) delete mode 100644 MediaBrowser.Model/Updates/PackageTargetSystem.cs delete mode 100644 MediaBrowser.Model/Updates/PackageVersionInfo.cs rename MediaBrowser.Model/Updates/{PackageVersionClass.cs => ReleaseChannel.cs} (51%) create mode 100644 MediaBrowser.Model/Updates/VersionInfo.cs diff --git a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs index ac8af66a20..0f0b8b97b1 100644 --- a/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs +++ b/Emby.Server.Implementations/Activity/ActivityLogEntryPoint.cs @@ -421,7 +421,7 @@ namespace Emby.Server.Implementations.Activity }); } - private void OnPluginUpdated(object sender, GenericEventArgs<(IPlugin, PackageVersionInfo)> e) + private void OnPluginUpdated(object sender, GenericEventArgs<(IPlugin, VersionInfo)> e) { CreateLogEntry(new ActivityLogEntry { @@ -433,7 +433,7 @@ namespace Emby.Server.Implementations.Activity ShortOverview = string.Format( CultureInfo.InvariantCulture, _localization.GetLocalizedString("VersionNumber"), - e.Argument.Item2.versionStr), + e.Argument.Item2.versionString), Overview = e.Argument.Item2.description }); } @@ -450,7 +450,7 @@ namespace Emby.Server.Implementations.Activity }); } - private void OnPluginInstalled(object sender, GenericEventArgs e) + private void OnPluginInstalled(object sender, GenericEventArgs e) { CreateLogEntry(new ActivityLogEntry { @@ -462,7 +462,7 @@ namespace Emby.Server.Implementations.Activity ShortOverview = string.Format( CultureInfo.InvariantCulture, _localization.GetLocalizedString("VersionNumber"), - e.Argument.versionStr) + e.Argument.versionString) }); } diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index dee0edd26e..ad77ab8b48 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -212,14 +212,14 @@ namespace Emby.Server.Implementations public IFileSystem FileSystemManager { get; set; } /// - public PackageVersionClass SystemUpdateLevel + public ReleaseChannel SystemUpdateLevel { get { -#if BETA - return PackageVersionClass.Beta; +#if NIGHTLY + return PackageChannel.Nightly; #else - return PackageVersionClass.Release; + return ReleaseChannel.Stable; #endif } } @@ -1003,7 +1003,7 @@ namespace Emby.Server.Implementations AuthenticatedAttribute.AuthService = AuthService; } - private async void PluginInstalled(object sender, GenericEventArgs args) + private async void PluginInstalled(object sender, GenericEventArgs args) { string dir = Path.Combine(ApplicationPaths.PluginsPath, args.Argument.name); var types = Directory.EnumerateFiles(dir, "*.dll", SearchOption.AllDirectories) diff --git a/Emby.Server.Implementations/Updates/InstallationManager.cs b/Emby.Server.Implementations/Updates/InstallationManager.cs index c897036eb8..1450c74d2d 100644 --- a/Emby.Server.Implementations/Updates/InstallationManager.cs +++ b/Emby.Server.Implementations/Updates/InstallationManager.cs @@ -23,12 +23,12 @@ using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Updates { /// - /// Manages all install, uninstall and update operations (both plugins and system). + /// Manages all install, uninstall, and update operations for the system and individual plugins. /// public class InstallationManager : IInstallationManager { /// - /// The _logger. + /// The logger. /// private readonly ILogger _logger; private readonly IApplicationPaths _appPaths; @@ -101,10 +101,10 @@ namespace Emby.Server.Implementations.Updates public event EventHandler> PluginUninstalled; /// - public event EventHandler> PluginUpdated; + public event EventHandler> PluginUpdated; /// - public event EventHandler> PluginInstalled; + public event EventHandler> PluginInstalled; /// public IEnumerable CompletedInstallations => _completedInstallationsInternal; @@ -115,7 +115,7 @@ namespace Emby.Server.Implementations.Updates using (var response = await _httpClient.SendAsync( new HttpRequestOptions { - Url = "https://repo.jellyfin.org/releases/plugin/manifest.json", + Url = "https://repo.jellyfin.org/releases/plugin/manifest-water.json", CancellationToken = cancellationToken, CacheMode = CacheMode.Unconditional, CacheLength = TimeSpan.FromMinutes(3) @@ -148,48 +148,48 @@ namespace Emby.Server.Implementations.Updates } /// - public IEnumerable GetCompatibleVersions( - IEnumerable availableVersions, + public IEnumerable GetCompatibleVersions( + IEnumerable availableVersions, Version minVersion = null, - PackageVersionClass classification = PackageVersionClass.Release) + ReleaseChannel releaseChannel = ReleaseChannel.Stable) { var appVer = _applicationHost.ApplicationVersion; availableVersions = availableVersions - .Where(x => x.classification == classification - && Version.Parse(x.requiredVersionStr) <= appVer); + .Where(x => x.channel == releaseChannel + && Version.Parse(x.minimumServerVersion) <= appVer); if (minVersion != null) { - availableVersions = availableVersions.Where(x => x.Version >= minVersion); + availableVersions = availableVersions.Where(x => x.versionCode >= minVersion); } - return availableVersions.OrderByDescending(x => x.Version); + return availableVersions.OrderByDescending(x => x.versionCode); } /// - public IEnumerable GetCompatibleVersions( + public IEnumerable GetCompatibleVersions( IEnumerable availablePackages, string name = null, Guid guid = default, Version minVersion = null, - PackageVersionClass classification = PackageVersionClass.Release) + ReleaseChannel releaseChannel = ReleaseChannel.Stable) { var package = FilterPackages(availablePackages, name, guid).FirstOrDefault(); - // Package not found. + // Package not found in repository if (package == null) { - return Enumerable.Empty(); + return Enumerable.Empty(); } return GetCompatibleVersions( package.versions, minVersion, - classification); + releaseChannel); } /// - public async IAsyncEnumerable GetAvailablePluginUpdates([EnumeratorCancellation] CancellationToken cancellationToken = default) + public async IAsyncEnumerable GetAvailablePluginUpdates([EnumeratorCancellation] CancellationToken cancellationToken = default) { var catalog = await GetAvailablePackages(cancellationToken).ConfigureAwait(false); @@ -198,8 +198,8 @@ namespace Emby.Server.Implementations.Updates // Figure out what needs to be installed foreach (var plugin in _applicationHost.Plugins) { - var compatibleversions = GetCompatibleVersions(catalog, plugin.Name, plugin.Id, plugin.Version, systemUpdateLevel); - var version = compatibleversions.FirstOrDefault(y => y.Version > plugin.Version); + var compatibleVersions = GetCompatibleVersions(catalog, plugin.Name, plugin.Id, plugin.Version, systemUpdateLevel); + var version = compatibleVersions.FirstOrDefault(y => y.versionCode > plugin.Version); if (version != null && !CompletedInstallations.Any(x => string.Equals(x.AssemblyGuid, version.guid, StringComparison.OrdinalIgnoreCase))) { @@ -209,7 +209,7 @@ namespace Emby.Server.Implementations.Updates } /// - public async Task InstallPackage(PackageVersionInfo package, CancellationToken cancellationToken) + public async Task InstallPackage(VersionInfo package, CancellationToken cancellationToken) { if (package == null) { @@ -221,8 +221,8 @@ namespace Emby.Server.Implementations.Updates Id = Guid.NewGuid(), Name = package.name, AssemblyGuid = package.guid, - UpdateClass = package.classification, - Version = package.versionStr + UpdateClass = package.channel, + Version = package.versionString }; var innerCancellationTokenSource = new CancellationTokenSource(); @@ -240,7 +240,7 @@ namespace Emby.Server.Implementations.Updates var installationEventArgs = new InstallationEventArgs { InstallationInfo = installationInfo, - PackageVersionInfo = package + VersionInfo = package }; PackageInstalling?.Invoke(this, installationEventArgs); @@ -265,7 +265,7 @@ namespace Emby.Server.Implementations.Updates _currentInstallations.Remove(tuple); } - _logger.LogInformation("Package installation cancelled: {0} {1}", package.name, package.versionStr); + _logger.LogInformation("Package installation cancelled: {0} {1}", package.name, package.versionString); PackageInstallationCancelled?.Invoke(this, installationEventArgs); @@ -301,7 +301,7 @@ namespace Emby.Server.Implementations.Updates /// The package. /// The cancellation token. /// . - private async Task InstallPackageInternal(PackageVersionInfo package, CancellationToken cancellationToken) + private async Task InstallPackageInternal(VersionInfo package, CancellationToken cancellationToken) { // Set last update time if we were installed before IPlugin plugin = _applicationHost.Plugins.FirstOrDefault(p => string.Equals(p.Id.ToString(), package.guid, StringComparison.OrdinalIgnoreCase)) @@ -313,26 +313,26 @@ namespace Emby.Server.Implementations.Updates // Do plugin-specific processing if (plugin == null) { - _logger.LogInformation("New plugin installed: {0} {1} {2}", package.name, package.versionStr ?? string.Empty, package.classification); + _logger.LogInformation("New plugin installed: {0} {1} {2}", package.name, package.versionString ?? string.Empty, package.channel); - PluginInstalled?.Invoke(this, new GenericEventArgs(package)); + PluginInstalled?.Invoke(this, new GenericEventArgs(package)); } else { - _logger.LogInformation("Plugin updated: {0} {1} {2}", package.name, package.versionStr ?? string.Empty, package.classification); + _logger.LogInformation("Plugin updated: {0} {1} {2}", package.name, package.versionString ?? string.Empty, package.channel); - PluginUpdated?.Invoke(this, new GenericEventArgs<(IPlugin, PackageVersionInfo)>((plugin, package))); + PluginUpdated?.Invoke(this, new GenericEventArgs<(IPlugin, VersionInfo)>((plugin, package))); } _applicationHost.NotifyPendingRestart(); } - private async Task PerformPackageInstallation(PackageVersionInfo package, CancellationToken cancellationToken) + private async Task PerformPackageInstallation(VersionInfo package, CancellationToken cancellationToken) { - var extension = Path.GetExtension(package.targetFilename); + var extension = Path.GetExtension(package.filename); if (!string.Equals(extension, ".zip", StringComparison.OrdinalIgnoreCase)) { - _logger.LogError("Only zip packages are supported. {Filename} is not a zip archive.", package.targetFilename); + _logger.LogError("Only zip packages are supported. {Filename} is not a zip archive.", package.filename); return; } @@ -379,7 +379,7 @@ namespace Emby.Server.Implementations.Updates } /// - /// Uninstalls a plugin + /// Uninstalls a plugin. /// /// The plugin. public void UninstallPlugin(IPlugin plugin) diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs index afc3e026a8..ccc978295c 100644 --- a/MediaBrowser.Api/PackageService.cs +++ b/MediaBrowser.Api/PackageService.cs @@ -42,23 +42,6 @@ namespace MediaBrowser.Api [Authenticated] public class GetPackages : IReturn { - /// - /// Gets or sets the name. - /// - /// The name. - [ApiMember(Name = "PackageType", Description = "Optional package type filter (System/UserInstalled)", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] - public string PackageType { get; set; } - - [ApiMember(Name = "TargetSystems", Description = "Optional. Filter by target system type. Allows multiple, comma delimited.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] - public string TargetSystems { get; set; } - - [ApiMember(Name = "IsPremium", Description = "Optional. Filter by premium status", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] - public bool? IsPremium { get; set; } - - [ApiMember(Name = "IsAdult", Description = "Optional. Filter by package that contain adult content.", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")] - public bool? IsAdult { get; set; } - - public bool? IsAppStoreEnabled { get; set; } } /// @@ -94,7 +77,7 @@ namespace MediaBrowser.Api /// /// The update class. [ApiMember(Name = "UpdateClass", Description = "Optional update class (Dev, Beta, Release). Defaults to Release.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] - public PackageVersionClass UpdateClass { get; set; } + public ReleaseChannel UpdateClass { get; set; } } /// @@ -154,23 +137,6 @@ namespace MediaBrowser.Api { IEnumerable packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); - if (!string.IsNullOrEmpty(request.TargetSystems)) - { - var apps = request.TargetSystems.Split(',').Select(i => (PackageTargetSystem)Enum.Parse(typeof(PackageTargetSystem), i, true)); - - packages = packages.Where(p => apps.Contains(p.targetSystem)); - } - - if (request.IsAdult.HasValue) - { - packages = packages.Where(p => p.adult == request.IsAdult.Value); - } - - if (request.IsAppStoreEnabled.HasValue) - { - packages = packages.Where(p => p.enableInAppStore == request.IsAppStoreEnabled.Value); - } - return ToOptimizedResult(packages.ToArray()); } diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs index 08964420e7..bc002e5233 100644 --- a/MediaBrowser.Common/Extensions/BaseExtensions.cs +++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs @@ -35,7 +35,6 @@ namespace MediaBrowser.Common.Extensions { return new Guid(provider.ComputeHash(Encoding.Unicode.GetBytes(str))); } - #pragma warning restore CA5351 } } diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs index 68a24aabaa..c88eac27a1 100644 --- a/MediaBrowser.Common/IApplicationHost.cs +++ b/MediaBrowser.Common/IApplicationHost.cs @@ -50,8 +50,8 @@ namespace MediaBrowser.Common /// /// Gets the version class of the system. /// - /// or . - PackageVersionClass SystemUpdateLevel { get; } + /// or . + ReleaseChannel SystemUpdateLevel { get; } /// /// Gets the application version. diff --git a/MediaBrowser.Common/Plugins/BasePlugin.cs b/MediaBrowser.Common/Plugins/BasePlugin.cs index b24d10ff10..9e4a360c38 100644 --- a/MediaBrowser.Common/Plugins/BasePlugin.cs +++ b/MediaBrowser.Common/Plugins/BasePlugin.cs @@ -67,7 +67,7 @@ namespace MediaBrowser.Common.Plugins } /// - /// Called when just before the plugin is uninstalled from the server. + /// Called just before the plugin is uninstalled from the server. /// public virtual void OnUninstalling() { @@ -101,7 +101,7 @@ namespace MediaBrowser.Common.Plugins private readonly object _configurationSyncLock = new object(); /// - /// The save lock. + /// The configuration save lock. /// private readonly object _configurationSaveLock = new object(); @@ -148,7 +148,7 @@ namespace MediaBrowser.Common.Plugins protected string AssemblyFileName => Path.GetFileName(AssemblyFilePath); /// - /// Gets or sets the plugin's configuration. + /// Gets or sets the plugin configuration. /// /// The configuration. public TConfigurationType Configuration @@ -186,7 +186,7 @@ namespace MediaBrowser.Common.Plugins public string ConfigurationFilePath => Path.Combine(ApplicationPaths.PluginConfigurationsPath, ConfigurationFileName); /// - /// Gets the plugin's configuration. + /// Gets the plugin configuration. /// /// The configuration. BasePluginConfiguration IHasPluginConfiguration.Configuration => Configuration; diff --git a/MediaBrowser.Common/Updates/IInstallationManager.cs b/MediaBrowser.Common/Updates/IInstallationManager.cs index a09c1916c5..284e418d9d 100644 --- a/MediaBrowser.Common/Updates/IInstallationManager.cs +++ b/MediaBrowser.Common/Updates/IInstallationManager.cs @@ -29,12 +29,12 @@ namespace MediaBrowser.Common.Updates /// /// Occurs when a plugin is updated. /// - event EventHandler> PluginUpdated; + event EventHandler> PluginUpdated; /// /// Occurs when a plugin is installed. /// - event EventHandler> PluginInstalled; + event EventHandler> PluginInstalled; /// /// Gets the completed installations. @@ -65,12 +65,12 @@ namespace MediaBrowser.Common.Updates /// /// The available version of the plugin. /// The minimum required version of the plugin. - /// The classification of updates. + /// The classification of updates. /// All compatible versions ordered from newest to oldest. - IEnumerable GetCompatibleVersions( - IEnumerable availableVersions, + IEnumerable GetCompatibleVersions( + IEnumerable availableVersions, Version minVersion = null, - PackageVersionClass classification = PackageVersionClass.Release); + ReleaseChannel releaseChannel = ReleaseChannel.Stable); /// /// Returns all compatible versions ordered from newest to oldest. @@ -79,21 +79,21 @@ namespace MediaBrowser.Common.Updates /// The name. /// The guid of the plugin. /// The minimum required version of the plugin. - /// The classification. + /// The classification. /// All compatible versions ordered from newest to oldest. - IEnumerable GetCompatibleVersions( + IEnumerable GetCompatibleVersions( IEnumerable availablePackages, string name = null, Guid guid = default, Version minVersion = null, - PackageVersionClass classification = PackageVersionClass.Release); + ReleaseChannel releaseChannel = ReleaseChannel.Stable); /// /// Returns the available plugin updates. /// /// The cancellation token. /// The available plugin updates. - IAsyncEnumerable GetAvailablePluginUpdates(CancellationToken cancellationToken = default); + IAsyncEnumerable GetAvailablePluginUpdates(CancellationToken cancellationToken = default); /// /// Installs the package. @@ -101,7 +101,7 @@ namespace MediaBrowser.Common.Updates /// The package. /// The cancellation token. /// . - Task InstallPackage(PackageVersionInfo package, CancellationToken cancellationToken = default); + Task InstallPackage(VersionInfo package, CancellationToken cancellationToken = default); /// /// Uninstalls a plugin. diff --git a/MediaBrowser.Common/Updates/InstallationEventArgs.cs b/MediaBrowser.Common/Updates/InstallationEventArgs.cs index 8bbb231ce1..f459fd8256 100644 --- a/MediaBrowser.Common/Updates/InstallationEventArgs.cs +++ b/MediaBrowser.Common/Updates/InstallationEventArgs.cs @@ -9,6 +9,6 @@ namespace MediaBrowser.Common.Updates { public InstallationInfo InstallationInfo { get; set; } - public PackageVersionInfo PackageVersionInfo { get; set; } + public VersionInfo VersionInfo { get; set; } } } diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 6576657662..41644ad334 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -11,7 +11,7 @@ netstandard2.1 false true - true + true diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 190411c9ba..da39ee208a 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -27,7 +27,7 @@ namespace MediaBrowser.Model.System /// public class SystemInfo : PublicSystemInfo { - public PackageVersionClass SystemUpdateLevel { get; set; } + public ReleaseChannel SystemUpdateLevel { get; set; } /// /// Gets or sets the display name of the operating system. diff --git a/MediaBrowser.Model/Updates/CheckForUpdateResult.cs b/MediaBrowser.Model/Updates/CheckForUpdateResult.cs index be1b082238..883fc636b4 100644 --- a/MediaBrowser.Model/Updates/CheckForUpdateResult.cs +++ b/MediaBrowser.Model/Updates/CheckForUpdateResult.cs @@ -17,13 +17,13 @@ namespace MediaBrowser.Model.Updates /// The available version. public string AvailableVersion { - get => Package != null ? Package.versionStr : "0.0.0.1"; + get => Package != null ? Package.versionString : "0.0.0.1"; set { } // need this for the serializer } /// /// Get or sets package information for an available update /// - public PackageVersionInfo Package { get; set; } + public VersionInfo Package { get; set; } } } diff --git a/MediaBrowser.Model/Updates/InstallationInfo.cs b/MediaBrowser.Model/Updates/InstallationInfo.cs index 42c2105f54..870bf8c0be 100644 --- a/MediaBrowser.Model/Updates/InstallationInfo.cs +++ b/MediaBrowser.Model/Updates/InstallationInfo.cs @@ -35,6 +35,6 @@ namespace MediaBrowser.Model.Updates /// Gets or sets the update class. /// /// The update class. - public PackageVersionClass UpdateClass { get; set; } + public ReleaseChannel UpdateClass { get; set; } } } diff --git a/MediaBrowser.Model/Updates/PackageInfo.cs b/MediaBrowser.Model/Updates/PackageInfo.cs index abbe91eff6..d06ffe1e6c 100644 --- a/MediaBrowser.Model/Updates/PackageInfo.cs +++ b/MediaBrowser.Model/Updates/PackageInfo.cs @@ -8,12 +8,6 @@ namespace MediaBrowser.Model.Updates /// public class PackageInfo { - /// - /// The internal id of this package. - /// - /// The id. - public string id { get; set; } - /// /// Gets or sets the name. /// @@ -32,24 +26,6 @@ namespace MediaBrowser.Model.Updates /// The overview. public string overview { get; set; } - /// - /// Gets or sets a value indicating whether this instance is premium. - /// - /// true if this instance is premium; otherwise, false. - public bool isPremium { get; set; } - - /// - /// Gets or sets a value indicating whether this instance is adult only content. - /// - /// true if this instance is adult; otherwise, false. - public bool adult { get; set; } - - /// - /// Gets or sets the rich desc URL. - /// - /// The rich desc URL. - public string richDescUrl { get; set; } - /// /// Gets or sets the thumb image. /// @@ -63,16 +39,10 @@ namespace MediaBrowser.Model.Updates public string previewImage { get; set; } /// - /// Gets or sets the type. - /// - /// The type. - public string type { get; set; } - - /// - /// Gets or sets the target filename. + /// Gets or sets the target filename for the downloaded binary. /// /// The target filename. - public string targetFilename { get; set; } + public string filename { get; set; } /// /// Gets or sets the owner. @@ -87,90 +57,24 @@ namespace MediaBrowser.Model.Updates public string category { get; set; } /// - /// Gets or sets the catalog tile color. - /// - /// The owner. - public string tileColor { get; set; } - - /// - /// Gets or sets the feature id of this package (if premium). - /// - /// The feature id. - public string featureId { get; set; } - - /// - /// Gets or sets the registration info for this package (if premium). - /// - /// The registration info. - public string regInfo { get; set; } - - /// - /// Gets or sets the price for this package (if premium). - /// - /// The price. - public float price { get; set; } - - /// - /// Gets or sets the target system for this plug-in (Server, MBTheater, MBClassic). - /// - /// The target system. - public PackageTargetSystem targetSystem { get; set; } - - /// - /// The guid of the assembly associated with this package (if a plug-in). + /// The guid of the assembly associated with this plugin. /// This is used to identify the proper item for automatic updates. /// /// The name. public string guid { get; set; } - /// - /// Gets or sets the total number of ratings for this package. - /// - /// The total ratings. - public int? totalRatings { get; set; } - - /// - /// Gets or sets the average rating for this package . - /// - /// The rating. - public float avgRating { get; set; } - - /// - /// Gets or sets whether or not this package is registered. - /// - /// True if registered. - public bool isRegistered { get; set; } - - /// - /// Gets or sets the expiration date for this package. - /// - /// Expiration Date. - public DateTime expDate { get; set; } - /// /// Gets or sets the versions. /// /// The versions. - public IReadOnlyList versions { get; set; } - - /// - /// Gets or sets a value indicating whether [enable in application store]. - /// - /// true if [enable in application store]; otherwise, false. - public bool enableInAppStore { get; set; } - - /// - /// Gets or sets the installs. - /// - /// The installs. - public int installs { get; set; } + public IReadOnlyList versions { get; set; } /// /// Initializes a new instance of the class. /// public PackageInfo() { - versions = Array.Empty(); + versions = Array.Empty(); } } } diff --git a/MediaBrowser.Model/Updates/PackageTargetSystem.cs b/MediaBrowser.Model/Updates/PackageTargetSystem.cs deleted file mode 100644 index 11af7f02dd..0000000000 --- a/MediaBrowser.Model/Updates/PackageTargetSystem.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace MediaBrowser.Model.Updates -{ - /// - /// Enum PackageType. - /// - public enum PackageTargetSystem - { - /// - /// Server. - /// - Server, - - /// - /// MB Theater. - /// - MBTheater, - - /// - /// MB Classic. - /// - MBClassic - } -} diff --git a/MediaBrowser.Model/Updates/PackageVersionInfo.cs b/MediaBrowser.Model/Updates/PackageVersionInfo.cs deleted file mode 100644 index 85d8fde860..0000000000 --- a/MediaBrowser.Model/Updates/PackageVersionInfo.cs +++ /dev/null @@ -1,97 +0,0 @@ -#pragma warning disable CS1591 -#pragma warning disable SA1600 - -using System; -using System.Text.Json.Serialization; - -namespace MediaBrowser.Model.Updates -{ - /// - /// Class PackageVersionInfo. - /// - public class PackageVersionInfo - { - /// - /// Gets or sets the name. - /// - /// The name. - public string name { get; set; } - - /// - /// Gets or sets the guid. - /// - /// The guid. - public string guid { get; set; } - - /// - /// Gets or sets the version STR. - /// - /// The version STR. - public string versionStr { get; set; } - - /// - /// The _version - /// - private Version _version; - - /// - /// Gets or sets the version. - /// Had to make this an interpreted property since Protobuf can't handle Version - /// - /// The version. - [JsonIgnore] - public Version Version - { - get - { - if (_version == null) - { - var ver = versionStr; - _version = new Version(string.IsNullOrEmpty(ver) ? "0.0.0.1" : ver); - } - - return _version; - } - } - - /// - /// Gets or sets the classification. - /// - /// The classification. - public PackageVersionClass classification { get; set; } - - /// - /// Gets or sets the description. - /// - /// The description. - public string description { get; set; } - - /// - /// Gets or sets the required version STR. - /// - /// The required version STR. - public string requiredVersionStr { get; set; } - - /// - /// Gets or sets the source URL. - /// - /// The source URL. - public string sourceUrl { get; set; } - - /// - /// Gets or sets the source URL. - /// - /// The source URL. - public string checksum { get; set; } - - /// - /// Gets or sets the target filename. - /// - /// The target filename. - public string targetFilename { get; set; } - - public string infoUrl { get; set; } - - public string runtimes { get; set; } - } -} diff --git a/MediaBrowser.Model/Updates/PackageVersionClass.cs b/MediaBrowser.Model/Updates/ReleaseChannel.cs similarity index 51% rename from MediaBrowser.Model/Updates/PackageVersionClass.cs rename to MediaBrowser.Model/Updates/ReleaseChannel.cs index f813f2c974..ed4a774a72 100644 --- a/MediaBrowser.Model/Updates/PackageVersionClass.cs +++ b/MediaBrowser.Model/Updates/ReleaseChannel.cs @@ -3,21 +3,16 @@ namespace MediaBrowser.Model.Updates /// /// Enum PackageVersionClass. /// - public enum PackageVersionClass + public enum ReleaseChannel { /// - /// The release. + /// The stable. /// - Release = 0, + Stable = 0, /// - /// The beta. + /// The nightly. /// - Beta = 1, - - /// - /// The dev. - /// - Dev = 2 + Nightly = 1 } } diff --git a/MediaBrowser.Model/Updates/VersionInfo.cs b/MediaBrowser.Model/Updates/VersionInfo.cs new file mode 100644 index 0000000000..ad893db2e2 --- /dev/null +++ b/MediaBrowser.Model/Updates/VersionInfo.cs @@ -0,0 +1,73 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1600 + +using System; + +namespace MediaBrowser.Model.Updates +{ + /// + /// Class PackageVersionInfo. + /// + public class VersionInfo + { + /// + /// Gets or sets the name. + /// + /// The name. + public string name { get; set; } + + /// + /// Gets or sets the guid. + /// + /// The guid. + public string guid { get; set; } + + /// + /// Gets or sets the version string. + /// + /// The version string. + public string versionString { get; set; } + + /// + /// Gets or sets the version. + /// + /// The version. + public Version versionCode { get; set; } + + /// + /// Gets or sets the release channel. + /// + /// The release channel for a given package version. + public ReleaseChannel channel { get; set; } + + /// + /// Gets or sets the description. + /// + /// The description. + public string description { get; set; } + + /// + /// Gets or sets the minimum required version for the server. + /// + /// The minimum required version. + public string minimumServerVersion { get; set; } + + /// + /// Gets or sets the source URL. + /// + /// The source URL. + public string sourceUrl { get; set; } + + /// + /// Gets or sets a checksum for the binary. + /// + /// The checksum. + public string checksum { get; set; } + + /// + /// Gets or sets the target filename for the downloaded binary. + /// + /// The target filename. + public string filename { get; set; } + } +} From 5d760b7ee806d3fb00ac5aa7d0981362526f1d11 Mon Sep 17 00:00:00 2001 From: Davide Polonio Date: Sun, 1 Mar 2020 21:38:34 +0100 Subject: [PATCH 0011/1003] 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 0012/1003] 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 0013/1003] 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 0014/1003] 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 0015/1003] 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 681dd8d32fbb4fdb67a4b82125179bd40d03edbd Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Tue, 17 Mar 2020 14:21:00 +0100 Subject: [PATCH 0016/1003] Add recommended extensions to VS Code configuration --- .vscode/extensions.json | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .vscode/extensions.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000000..59d9452fed --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,14 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. + // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp + + // List of extensions which should be recommended for users of this workspace. + "recommendations": [ + "ms-dotnettools.csharp", + "editorconfig.editorconfig" + ], + // List of extensions recommended by VS Code that should not be recommended for users of this workspace. + "unwantedRecommendations": [ + + ] +} From 751dff09dc6f57be14f071346a79a23f33fa48c5 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Tue, 17 Mar 2020 14:21:24 +0100 Subject: [PATCH 0017/1003] Add development instructions to README with details on running from source --- README.md | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/README.md b/README.md index ea54b8c8b0..74042d8d83 100644 --- a/README.md +++ b/README.md @@ -63,3 +63,92 @@ Most of the translations can be found in the web client but we have several othe Detailed Translation Status + +## Development + +These instructions will help you get set up with a local development environment in order to contribute to this repository. Before you start, please be sure to completely read our [guidelines on development contributions](https://jellyfin.org/docs/general/contributing/development.html). Note that this project is supported on all major operating systems (Windows, Mac and Linux). + +### Prerequisites + +The following software prerequisites are required to be installed locally before the project can be built and executed. + +* [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) +* [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least version 2017) or [Visual Studio Code](https://code.visualstudio.com/Download) + +### Cloning the Repository + +After dependencies are installed you will need to clone a local copy of this repository. If you just want to run the server from source you can clone this repository directly, but if you are intending to contribute code changes to the project, you should [set up your own fork](https://jellyfin.org/docs/general/contributing/development.html#set-up-your-copy-of-the-repo) of the repository. The following example shows how you can clone the repository directly over HTTPS. + +```bash +git clone https://github.com/jellyfin/jellyfin.git +``` + +### Installing the Web Client + +By default, the server is configured to host the static files required for the [web client](https://github.com/jellyfin/jellyfin-web) in addition to serving the backend API. before you can run the server, you will need to get a copy of the web client files since they are not included in this repository directly. + +Note that it is also possible to [host the web client separately](#hosting-the-web-client-separately) from the web server with some additional configuration, in which case you can skip this step. + +There are two options to get the files for the web client: + +1. Build them from source following the instructions on the [jellyfin-web repository](https://github.com/jellyfin/jellyfin-web) +2. Get the pre-built files from an existing installation of the server. For example, with a Windows server installation the client files are located here: `C:\Program Files\Jellyfin\Server\jellyfin-web` + +Once you have a copy of the built web client files, you need to copy them into the build output directory of the web server project. For example: `\Jellyfin.Server\bin\Debug\netcoreapp3.1\jellyfin-web` + +### Running The Server + +The following instructions will help you get the project up and running via the command line, or your preferred IDE. + +#### Running With Visual Studio + +To run the project with Visual Studio you can open the Solution (`.sln`) file and then press `F5` to run the server. + +#### Running With Visual Studio Code + +To run the project with Visual Studio Code you will first need to open the repository directory with Visual Studio Code using the `Open Folder...` option. + +Second, you need to [install the recommended extensions for the workspace](https://code.visualstudio.com/docs/editor/extension-gallery#_recommended-extensions). Note that extension recommendations are classified as either "Workspace Recommendations" or "Other Recommendations", but only the "Workspace Recommendations" are required. + +After the required extensions are installed, you can can run the server by pressing `F5`. + +#### Running From The Command Line + +To run the server from the command line you can use the `dotnet run` command. The example below shows how to do this if you have cloned the repository into a directory named `jellyfin` (the default directory name) and should work on all operating systems. + +```bash +cd jellyfin # Move into the repository directory +cd Jellyfin.Server # Move into the server startup project directory +dotnet run # Run the server startup project +``` + +A second option is to build the project and then run the resulting executable file directly. When running the executable directly you can easily add command line options. Add the `--help` flag to list details on all the supported command line options. + +1. Build the project + + ```bash + dotnet build # Build the project + cd bin/Debug/netcoreapp3.1 # Change into the build output directory + ``` + +2. Execute the build output. On Linux, Mac, etc. use `./jellyfin` and on Windows use `jellyfin.exe`. + +### Running The Tests + +This repository also includes several unit test projects that are used to validate functionality as part of a CI process. These are several ways to run these tests: + +1. Run tests from the command line using `dotnet test` +2. Run tests in Visual Studio using the [Test Explorer](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer) +3. Run individual tests in Visual Studio Code using the associated [CodeLens annotation](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests) + +### Advanced Configuration + +The following sections describe some more advanced scenarios for running the server from source that build upon the standard instructions above. + +#### Hosting The Web Client Separately + +It is not necessary to host the frontend web client as part of the backend server. Hosting these two components separately may be useful for front-end developers who would prefer to host the client in a separate webpack development server for a tighter development loop (see the [jellyfin-web](https://github.com/jellyfin/jellyfin-web#getting-started) repo for instructions on how to do this). + +To instruct the server not to host the web content, there is a `nowebcontent` configuration flag that must be set. This can specified using the command line switch `--nowebcontent` or the environment variable `JELLYFIN_NOWEBCONTENT=true`. + +Since this is a common scenario, there is also a separate launch profile defined for Visual Studio called `Jellyfin.Server (nowebcontent)` that can be selected from the 'Start Debugging' dropdown in the main toolbar. 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 0018/1003] 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 0019/1003] 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 0020/1003] 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 48f33f9a9669d0a237c85278a0cac3d3240a7c49 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 20 Mar 2020 12:21:20 +0100 Subject: [PATCH 0021/1003] Reword prerequisite section so that IDEs are listed as optional --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 74042d8d83..d7f2da7900 100644 --- a/README.md +++ b/README.md @@ -70,10 +70,9 @@ These instructions will help you get set up with a local development environment ### Prerequisites -The following software prerequisites are required to be installed locally before the project can be built and executed. +Before the the project can be built, you must first install the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) on your system. -* [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) -* [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least version 2017) or [Visual Studio Code](https://code.visualstudio.com/Download) +Instructions to run this project from the command line are included here, but you will also need to install an IDE if you want to debug the server while it is running. Any IDE that supports .NET Core development will work, but explicit instructions for [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least 2017) and [Visual Studio Code](https://code.visualstudio.com/Download) are included here. ### Cloning the Repository From cd34115e9981185e6a4f286d81f10160990e3f7c Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 20 Mar 2020 12:35:01 +0100 Subject: [PATCH 0022/1003] Remove duplicate text Co-Authored-By: artiume --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d7f2da7900..95659e8a8c 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ These instructions will help you get set up with a local development environment ### Prerequisites -Before the the project can be built, you must first install the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) on your system. +Before the project can be built, you must first install the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) on your system. Instructions to run this project from the command line are included here, but you will also need to install an IDE if you want to debug the server while it is running. Any IDE that supports .NET Core development will work, but explicit instructions for [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least 2017) and [Visual Studio Code](https://code.visualstudio.com/Download) are included here. From 3fd245ba8789e862a67f41d5c481ccab6a49fb33 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 21 Mar 2020 23:03:00 +0100 Subject: [PATCH 0023/1003] Add instructions for serving content over HTTPS --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 95659e8a8c..7b08723d6a 100644 --- a/README.md +++ b/README.md @@ -151,3 +151,9 @@ It is not necessary to host the frontend web client as part of the backend serve To instruct the server not to host the web content, there is a `nowebcontent` configuration flag that must be set. This can specified using the command line switch `--nowebcontent` or the environment variable `JELLYFIN_NOWEBCONTENT=true`. Since this is a common scenario, there is also a separate launch profile defined for Visual Studio called `Jellyfin.Server (nowebcontent)` that can be selected from the 'Start Debugging' dropdown in the main toolbar. + +#### Serving Over HTTPS + +The .NET Core SDK includes a certificate that can be used to serve content over HTTPS while developing. When running from Visual Studio, VS Code, or using `dotnet run`, this behavior is automatically enabled by setting the environment variable `ASPNETCORE_ENVIRONMENT=Development` and you can access the HTTPS version of the site at https://localhost:8920. + +By default, the development certificate is not trusted so you will see a security warning when you browse to the site over HTTPS. On most browsers you can easily bypass this warning and continue to the site. However, if you want to get rid of the warning, you can configure your machine to trust the development certificate by following the instructions in the [ASP.NET Core documentation](https://docs.microsoft.com/en-us/aspnet/core/security/enforcing-ssl#trust-the-aspnet-core-https-development-certificate-on-windows-and-macos). From 9bdb99fe92edaf06679ef855eae9f8bb69b970df Mon Sep 17 00:00:00 2001 From: Luke Foust Date: Sun, 22 Mar 2020 12:58:53 -0700 Subject: [PATCH 0024/1003] Add type to externalids to distinguish them in the UI --- .../Providers/IExternalId.cs | 19 +++++++++++++ .../Providers/ExternalIdInfo.cs | 6 ++++ .../Manager/ProviderManager.cs | 1 + .../Movies/MovieExternalIds.cs | 6 ++++ .../Music/MusicExternalIds.cs | 3 ++ .../Plugins/AudioDb/ExternalIds.cs | 16 +++++++++-- .../Plugins/MusicBrainz/ExternalIds.cs | 28 +++++++++++++++---- MediaBrowser.Providers/TV/TvExternalIds.cs | 12 ++++++++ .../Tmdb/BoxSets/TmdbBoxSetExternalId.cs | 3 ++ .../Tmdb/Movies/TmdbMovieExternalId.cs | 3 ++ .../Tmdb/People/TmdbPersonExternalId.cs | 3 ++ .../Tmdb/TV/TmdbSeriesExternalId.cs | 3 ++ 12 files changed, 96 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index d7e337bdab..157a2076eb 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -8,8 +8,27 @@ namespace MediaBrowser.Controller.Providers string Key { get; } + ExternalIdType Type { get; } + string UrlFormatString { get; } bool Supports(IHasProviderIds item); } + + public enum ExternalIdType + { + None, + Album, + AlbumArtist, + Artist, + BoxSet, + Episode, + Movie, + OtherArtist, + Person, + ReleaseGroup, + Season, + Series, + Track + } } diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 2b481ad7ed..8d6d911434 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -16,6 +16,12 @@ namespace MediaBrowser.Model.Providers /// The key. public string Key { get; set; } + /// + /// Gets or sets the type. + /// + /// The type. + public string Type { get; set; } + /// /// Gets or sets the URL format string. /// diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index e7b349f67b..608a0cd194 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -910,6 +910,7 @@ namespace MediaBrowser.Providers.Manager { Name = i.Name, Key = i.Key, + Type = i.Type == ExternalIdType.None ? null : i.Type.ToString(), UrlFormatString = i.UrlFormatString }); diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 55810b1ed8..1ede0e7a5f 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -15,6 +15,9 @@ namespace MediaBrowser.Providers.Movies /// public string Key => MetadataProviders.Imdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => "https://www.imdb.com/title/{0}"; @@ -39,6 +42,9 @@ namespace MediaBrowser.Providers.Movies /// public string Key => MetadataProviders.Imdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Person; + /// public string UrlFormatString => "https://www.imdb.com/name/{0}"; diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 628b9a9a10..54e0347138 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Music /// public string Key => "IMVDb"; + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => null; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index 2d8cb431ca..785185d61f 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Plugins.AudioDb /// public string Key => MetadataProviders.AudioDbAlbum.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -22,11 +25,14 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbOtherAlbumExternalId : IExternalId { /// - public string Name => "TheAudioDb Album"; + public string Name => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbAlbum.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Album; + /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -42,6 +48,9 @@ namespace MediaBrowser.Providers.Plugins.AudioDb /// public string Key => MetadataProviders.AudioDbArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Artist; + /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; @@ -52,11 +61,14 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbOtherArtistExternalId : IExternalId { /// - public string Name => "TheAudioDb Artist"; + public string Name => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.OtherArtist; + /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index 03565a34c4..ed9fa6307f 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -8,11 +8,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzReleaseGroupExternalId : IExternalId { /// - public string Name => "MusicBrainz Release Group"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); + /// + public ExternalIdType Type => ExternalIdType.ReleaseGroup; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}"; @@ -23,11 +26,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzAlbumArtistExternalId : IExternalId { /// - public string Name => "MusicBrainz Album Artist"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.AlbumArtist; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -38,11 +44,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzAlbumExternalId : IExternalId { /// - public string Name => "MusicBrainz Album"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Album; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}"; @@ -58,6 +67,9 @@ namespace MediaBrowser.Providers.Music /// public string Key => MetadataProviders.MusicBrainzArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Artist; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -68,12 +80,15 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzOtherArtistExternalId : IExternalId { /// - public string Name => "MusicBrainz Artist"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.OtherArtist; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -84,11 +99,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzTrackId : IExternalId { /// - public string Name => "MusicBrainz Track"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzTrack.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Track; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}"; diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index baf8542851..a3c24f7dd4 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -13,6 +13,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Zap2It.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => "http://tvlistings.zap2it.com/overview.html?programSeriesId={0}"; @@ -28,6 +31,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Tvdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=series&id={0}"; @@ -44,6 +50,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Tvdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Season; + /// public string UrlFormatString => null; @@ -59,6 +68,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Tvdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Episode; + /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=episode&id={0}"; diff --git a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs index 187295e1e4..a51355254d 100644 --- a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs @@ -13,6 +13,9 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets /// public string Key => MetadataProviders.TmdbCollection.ToString(); + /// + public ExternalIdType Type => ExternalIdType.BoxSet; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "collection/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs index fc7a4583fd..af565b079b 100644 --- a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs @@ -14,6 +14,9 @@ namespace MediaBrowser.Providers.Tmdb.Movies /// public string Key => MetadataProviders.Tmdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Movie; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "movie/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs index 2c61bc70aa..1ec43c2696 100644 --- a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Tmdb.People /// public string Key => MetadataProviders.Tmdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Person; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "person/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs index 524a3b05e2..43ef06bf7a 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Tmdb.TV /// public string Key => MetadataProviders.Tmdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Series; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "tv/{0}"; From 2afbbba3f874884e7f249bacb9de458244242380 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 22 Mar 2020 16:00:20 -0400 Subject: [PATCH 0025/1003] 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 0026/1003] 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 0027/1003] 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 0028/1003] 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 0029/1003] 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 0030/1003] 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 0031/1003] 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 0032/1003] 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 0033/1003] 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 0034/1003] 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 0035/1003] 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 0036/1003] 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 0037/1003] 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 0038/1003] 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 0039/1003] 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 0040/1003] 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 0041/1003] 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 0042/1003] 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 0043/1003] 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 0044/1003] 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 0045/1003] 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 0046/1003] 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 0047/1003] 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 0048/1003] 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 0049/1003] 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 0050/1003] 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 0051/1003] 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 0052/1003] 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 0053/1003] 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 0054/1003] 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 0055/1003] 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 0056/1003] 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 0057/1003] 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 0058/1003] 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 798a76510506f4707564be208bf737ab6a4d80c1 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2020 17:15:32 +0000 Subject: [PATCH 0059/1003] Bump System.Text.Json from 4.7.0 to 4.7.1 Bumps [System.Text.Json](https://github.com/dotnet/corefx) from 4.7.0 to 4.7.1. - [Release notes](https://github.com/dotnet/corefx/releases) - [Commits](https://github.com/dotnet/corefx/commits) Signed-off-by: dependabot-preview[bot] --- MediaBrowser.Model/MediaBrowser.Model.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj index 0fdfe57619..27486c68f1 100644 --- a/MediaBrowser.Model/MediaBrowser.Model.csproj +++ b/MediaBrowser.Model/MediaBrowser.Model.csproj @@ -18,7 +18,7 @@ - + From 0fb78cf54b51843c54e7ff59d191c490a5b196cd Mon Sep 17 00:00:00 2001 From: Luke Foust Date: Thu, 26 Mar 2020 14:26:12 -0700 Subject: [PATCH 0060/1003] Add documentation around Name, Id, and Type. Changed ExternalIdType to ExternalIdMediaType --- .../Providers/ExternalIdMediaType.cs | 45 +++++++++++++++++++ .../Providers/IExternalId.cs | 27 ++++------- .../Providers/ExternalIdInfo.cs | 17 ++++--- .../Manager/ProviderManager.cs | 2 +- .../Movies/MovieExternalIds.cs | 4 +- .../Music/MusicExternalIds.cs | 2 +- .../Plugins/AudioDb/ExternalIds.cs | 8 ++-- .../Plugins/MusicBrainz/ExternalIds.cs | 12 ++--- MediaBrowser.Providers/TV/TvExternalIds.cs | 8 ++-- .../Tmdb/BoxSets/TmdbBoxSetExternalId.cs | 2 +- .../Tmdb/Movies/TmdbMovieExternalId.cs | 2 +- .../Tmdb/People/TmdbPersonExternalId.cs | 2 +- .../Tmdb/TV/TmdbSeriesExternalId.cs | 2 +- 13 files changed, 84 insertions(+), 49 deletions(-) create mode 100644 MediaBrowser.Controller/Providers/ExternalIdMediaType.cs diff --git a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs new file mode 100644 index 0000000000..470f1e24c0 --- /dev/null +++ b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs @@ -0,0 +1,45 @@ +namespace MediaBrowser.Controller.Providers +{ + /// The specific media type of an . + public enum ExternalIdMediaType + { + /// There is no specific media type + None, + + /// A music album + Album, + + /// The artist of a music album + AlbumArtist, + + /// The artist of a media item + Artist, + + /// A boxed set of media + BoxSet, + + /// A series episode + Episode, + + /// A movie + Movie, + + /// An alternative artist apart from the main artist + OtherArtist, + + /// A person + Person, + + /// A release group + ReleaseGroup, + + /// A single season of a series + Season, + + /// A series + Series, + + /// A music track + Track + } +} diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index 157a2076eb..c877ffe1fe 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -2,33 +2,24 @@ using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Providers { + /// Represents and identifier for an external provider. public interface IExternalId { + /// Gets the name used to identify this provider string Name { get; } + /// Gets the unique key to distinguish this provider/type pair. This should be unique across providers. string Key { get; } - ExternalIdType Type { get; } + /// Gets the specific media type for this id. + ExternalIdMediaType Type { get; } + /// Gets the url format string for this id. string UrlFormatString { get; } + /// Determines whether this id supports a given item type. + /// The item. + /// True if this item is supported, otherwise false. bool Supports(IHasProviderIds item); } - - public enum ExternalIdType - { - None, - Album, - AlbumArtist, - Artist, - BoxSet, - Episode, - Movie, - OtherArtist, - Person, - ReleaseGroup, - Season, - Series, - Track - } } diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 8d6d911434..befcc309bf 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -1,31 +1,30 @@ -#pragma warning disable CS1591 - namespace MediaBrowser.Model.Providers { + /// + /// Represents the external id information for serialization to the client. + /// public class ExternalIdInfo { /// - /// Gets or sets the name. + /// Gets or sets the name of the external id provider (IE: IMDB, MusicBrainz, etc). /// - /// The name. public string Name { get; set; } /// - /// Gets or sets the key. + /// Gets or sets the unique key for this id. This key should be unique across all providers. /// - /// The key. public string Key { get; set; } /// - /// Gets or sets the type. + /// Gets or sets the media type (Album, Artist, etc). + /// This can be null if there is no specific type. + /// This string is also used to localize the media type on the client. /// - /// The type. public string Type { get; set; } /// /// Gets or sets the URL format string. /// - /// The URL format string. public string UrlFormatString { get; set; } } } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 608a0cd194..fee988d50a 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -910,7 +910,7 @@ namespace MediaBrowser.Providers.Manager { Name = i.Name, Key = i.Key, - Type = i.Type == ExternalIdType.None ? null : i.Type.ToString(), + Type = i.Type == ExternalIdMediaType.None ? null : i.Type.ToString(), UrlFormatString = i.UrlFormatString }); diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 1ede0e7a5f..a7b359a2d8 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Providers.Movies public string Key => MetadataProviders.Imdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => "https://www.imdb.com/title/{0}"; @@ -43,7 +43,7 @@ namespace MediaBrowser.Providers.Movies public string Key => MetadataProviders.Imdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Person; + public ExternalIdMediaType Type => ExternalIdMediaType.Person; /// public string UrlFormatString => "https://www.imdb.com/name/{0}"; diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 54e0347138..19879411e1 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Music public string Key => "IMVDb"; /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => null; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index 785185d61f..cd65acb769 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbAlbum.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbAlbum.ToString(); /// - public ExternalIdType Type => ExternalIdType.Album; + public ExternalIdMediaType Type => ExternalIdMediaType.Album; /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.Artist; + public ExternalIdMediaType Type => ExternalIdMediaType.Artist; /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; @@ -67,7 +67,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.OtherArtist; + public ExternalIdMediaType Type => ExternalIdMediaType.OtherArtist; /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index ed9fa6307f..7d74a8d351 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); /// - public ExternalIdType Type => ExternalIdType.ReleaseGroup; + public ExternalIdMediaType Type => ExternalIdMediaType.ReleaseGroup; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}"; @@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.AlbumArtist; + public ExternalIdMediaType Type => ExternalIdMediaType.AlbumArtist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -50,7 +50,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); /// - public ExternalIdType Type => ExternalIdType.Album; + public ExternalIdMediaType Type => ExternalIdMediaType.Album; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}"; @@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.Artist; + public ExternalIdMediaType Type => ExternalIdMediaType.Artist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -87,7 +87,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.OtherArtist; + public ExternalIdMediaType Type => ExternalIdMediaType.OtherArtist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -105,7 +105,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzTrack.ToString(); /// - public ExternalIdType Type => ExternalIdType.Track; + public ExternalIdMediaType Type => ExternalIdMediaType.Track; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}"; diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index a3c24f7dd4..75d8b6bf58 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Zap2It.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => "http://tvlistings.zap2it.com/overview.html?programSeriesId={0}"; @@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=series&id={0}"; @@ -51,7 +51,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Season; + public ExternalIdMediaType Type => ExternalIdMediaType.Season; /// public string UrlFormatString => null; @@ -69,7 +69,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Episode; + public ExternalIdMediaType Type => ExternalIdMediaType.Episode; /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=episode&id={0}"; diff --git a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs index a51355254d..a83cde93c6 100644 --- a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets public string Key => MetadataProviders.TmdbCollection.ToString(); /// - public ExternalIdType Type => ExternalIdType.BoxSet; + public ExternalIdMediaType Type => ExternalIdMediaType.BoxSet; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "collection/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs index af565b079b..f9ea000676 100644 --- a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Providers.Tmdb.Movies public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Movie; + public ExternalIdMediaType Type => ExternalIdMediaType.Movie; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "movie/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs index 1ec43c2696..854fd41560 100644 --- a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Tmdb.People public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Person; + public ExternalIdMediaType Type => ExternalIdMediaType.Person; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "person/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs index 43ef06bf7a..770448c7f7 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Tmdb.TV public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Series; + public ExternalIdMediaType Type => ExternalIdMediaType.Series; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "tv/{0}"; From ee2f911a2b85792c2bfc867d42b7d58b847de6ea Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 00:10:16 +0100 Subject: [PATCH 0061/1003] Remove unnecessary CommonProcess abstraction --- .../ApplicationHost.cs | 11 +- .../Diagnostics/CommonProcess.cs | 152 ------------------ .../Diagnostics/ProcessFactory.cs | 5 +- .../LiveTv/EmbyTV/EmbyTV.cs | 18 ++- .../LiveTv/EmbyTV/EncodedRecorder.cs | 23 ++- .../Extensions/ProcessExtensions.cs | 66 ++++++++ .../Encoder/MediaEncoder.cs | 31 ++-- .../Subtitles/SubtitleEncoder.cs | 13 +- MediaBrowser.Model/Diagnostics/IProcess.cs | 23 --- .../Diagnostics/IProcessFactory.cs | 19 +-- 10 files changed, 120 insertions(+), 241 deletions(-) delete mode 100644 Emby.Server.Implementations/Diagnostics/CommonProcess.cs create mode 100644 MediaBrowser.Common/Extensions/ProcessExtensions.cs delete mode 100644 MediaBrowser.Model/Diagnostics/IProcess.cs diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index d6a572818a..bc637b02f1 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -1727,15 +1727,15 @@ namespace Emby.Server.Implementations throw new NotSupportedException(); } - var process = ProcessFactory.Create(new ProcessOptions + var process = ProcessFactory.Create(new ProcessStartInfo { FileName = url, - EnableRaisingEvents = true, UseShellExecute = true, ErrorDialog = false }); - process.Exited += ProcessExited; + process.EnableRaisingEvents = true; + process.Exited += (sender, args) => ((Process)sender).Dispose(); ; try { @@ -1748,11 +1748,6 @@ namespace Emby.Server.Implementations } } - private static void ProcessExited(object sender, EventArgs e) - { - ((IProcess)sender).Dispose(); - } - public virtual void EnableLoopback(string appName) { } diff --git a/Emby.Server.Implementations/Diagnostics/CommonProcess.cs b/Emby.Server.Implementations/Diagnostics/CommonProcess.cs deleted file mode 100644 index bfa49ac5ff..0000000000 --- a/Emby.Server.Implementations/Diagnostics/CommonProcess.cs +++ /dev/null @@ -1,152 +0,0 @@ -#pragma warning disable CS1591 - -using System; -using System.Diagnostics; -using System.IO; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.Diagnostics; - -namespace Emby.Server.Implementations.Diagnostics -{ - public class CommonProcess : IProcess - { - private readonly Process _process; - - private bool _disposed = false; - private bool _hasExited; - - public CommonProcess(ProcessOptions options) - { - StartInfo = options; - - var startInfo = new ProcessStartInfo - { - Arguments = options.Arguments, - FileName = options.FileName, - WorkingDirectory = options.WorkingDirectory, - UseShellExecute = options.UseShellExecute, - CreateNoWindow = options.CreateNoWindow, - RedirectStandardError = options.RedirectStandardError, - RedirectStandardInput = options.RedirectStandardInput, - RedirectStandardOutput = options.RedirectStandardOutput, - ErrorDialog = options.ErrorDialog - }; - - - if (options.IsHidden) - { - startInfo.WindowStyle = ProcessWindowStyle.Hidden; - } - - _process = new Process - { - StartInfo = startInfo - }; - - if (options.EnableRaisingEvents) - { - _process.EnableRaisingEvents = true; - _process.Exited += OnProcessExited; - } - } - - public event EventHandler Exited; - - public ProcessOptions StartInfo { get; } - - public StreamWriter StandardInput => _process.StandardInput; - - public StreamReader StandardError => _process.StandardError; - - public StreamReader StandardOutput => _process.StandardOutput; - - public int ExitCode => _process.ExitCode; - - private bool HasExited - { - get - { - if (_hasExited) - { - return true; - } - - try - { - _hasExited = _process.HasExited; - } - catch (InvalidOperationException) - { - _hasExited = true; - } - - return _hasExited; - } - } - - public void Start() - { - _process.Start(); - } - - public void Kill() - { - _process.Kill(); - } - - public bool WaitForExit(int timeMs) - { - return _process.WaitForExit(timeMs); - } - - public Task WaitForExitAsync(int timeMs) - { - // Note: For this function to work correctly, the option EnableRisingEvents needs to be set to true. - - if (HasExited) - { - return Task.FromResult(true); - } - - timeMs = Math.Max(0, timeMs); - - var tcs = new TaskCompletionSource(); - - var cancellationToken = new CancellationTokenSource(timeMs).Token; - - _process.Exited += (sender, args) => tcs.TrySetResult(true); - - cancellationToken.Register(() => tcs.TrySetResult(HasExited)); - - return tcs.Task; - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (_disposed) - { - return; - } - - if (disposing) - { - _process?.Dispose(); - } - - _disposed = true; - } - - private void OnProcessExited(object sender, EventArgs e) - { - _hasExited = true; - Exited?.Invoke(this, e); - } - } -} diff --git a/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs b/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs index 02ad3c1a89..00172e17a6 100644 --- a/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs +++ b/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs @@ -1,14 +1,15 @@ #pragma warning disable CS1591 +using System.Diagnostics; using MediaBrowser.Model.Diagnostics; namespace Emby.Server.Implementations.Diagnostics { public class ProcessFactory : IProcessFactory { - public IProcess Create(ProcessOptions options) + public Process Create(ProcessStartInfo startInfo) { - return new CommonProcess(options); + return new Process { StartInfo = startInfo }; } } } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 139aa19a4b..0f54022c8e 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -1683,19 +1684,19 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV try { - var process = _processFactory.Create(new ProcessOptions + var process = _processFactory.Create(new ProcessStartInfo { Arguments = GetPostProcessArguments(path, options.RecordingPostProcessorArguments), CreateNoWindow = true, - EnableRaisingEvents = true, ErrorDialog = false, FileName = options.RecordingPostProcessor, - IsHidden = true, + WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = false }); _logger.LogInformation("Running recording post processor {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + process.EnableRaisingEvents = true; process.Exited += Process_Exited; process.Start(); } @@ -1712,11 +1713,14 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private void Process_Exited(object sender, EventArgs e) { - using (var process = (IProcess)sender) + try { - _logger.LogInformation("Recording post-processing script completed with exit code {ExitCode}", process.ExitCode); - - process.Dispose(); + var exitCode = ((Process)sender).ExitCode; + _logger.LogInformation("Recording post-processing script completed with exit code {ExitCode}", exitCode); + } + finally + { + ((Process)sender).Dispose(); } } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 8590c56dfd..3591384de1 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Text; @@ -30,7 +31,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private bool _hasExited; private Stream _logFileStream; private string _targetPath; - private IProcess _process; + private Process _process; private readonly IProcessFactory _processFactory; private readonly IJsonSerializer _json; private readonly TaskCompletionSource _taskCompletionSource = new TaskCompletionSource(); @@ -80,7 +81,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV _targetPath = targetFile; Directory.CreateDirectory(Path.GetDirectoryName(targetFile)); - var process = _processFactory.Create(new ProcessOptions + _process = _processFactory.Create(new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -91,14 +92,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV FileName = _mediaEncoder.EncoderPath, Arguments = GetCommandLineArgs(mediaSource, inputFile, targetFile, duration), - IsHidden = true, - ErrorDialog = false, - EnableRaisingEvents = true + WindowStyle = ProcessWindowStyle.Hidden, + ErrorDialog = false }); - _process = process; - - var commandLineLogMessage = process.StartInfo.FileName + " " + process.StartInfo.Arguments; + var commandLineLogMessage = _process.StartInfo.FileName + " " + _process.StartInfo.Arguments; _logger.LogInformation(commandLineLogMessage); var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "record-transcode-" + Guid.NewGuid() + ".txt"); @@ -110,16 +108,17 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(_json.SerializeToString(mediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine); _logFileStream.Write(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length); - process.Exited += (sender, args) => OnFfMpegProcessExited(process, inputFile); + _process.EnableRaisingEvents = true; + _process.Exited += (sender, args) => OnFfMpegProcessExited(_process, inputFile); - process.Start(); + _process.Start(); cancellationToken.Register(Stop); onStarted(); // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback - StartStreamingLog(process.StandardError.BaseStream, _logFileStream); + StartStreamingLog(_process.StandardError.BaseStream, _logFileStream); _logger.LogInformation("ffmpeg recording process started for {0}", _targetPath); @@ -293,7 +292,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV /// /// Processes the exited. /// - private void OnFfMpegProcessExited(IProcess process, string inputFile) + private void OnFfMpegProcessExited(Process process, string inputFile) { _hasExited = true; diff --git a/MediaBrowser.Common/Extensions/ProcessExtensions.cs b/MediaBrowser.Common/Extensions/ProcessExtensions.cs new file mode 100644 index 0000000000..9fa0efdff8 --- /dev/null +++ b/MediaBrowser.Common/Extensions/ProcessExtensions.cs @@ -0,0 +1,66 @@ +using System; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Common.Extensions +{ + /// + /// Extension methods for . + /// + public static class ProcessExtensions + { + /// + /// Gets a value indicating whether the associated process has been terminated using + /// . This is safe to call even if there is no operating system process + /// associated with the . + /// + /// The process to check the exit status for. + /// + /// True if the operating system process referenced by the component has + /// terminated, or if there is no associated operating system process; otherwise, false. + /// + public static bool HasExitedSafe(this Process process) + { + try + { + return process.HasExited; + } + catch (InvalidOperationException) + { + return true; + } + } + + /// + /// Asynchronously wait for the process to exit. + /// + /// The process to wait for. + /// A timeout, in milliseconds, after which to stop waiting for the task. + /// True if the task exited normally, false if the timeout elapsed before the process exited. + public static async Task WaitForExitAsync(this Process process, int timeMs) + { + if (!process.EnableRaisingEvents) + { + throw new InvalidOperationException("EnableRisingEvents must be enabled to async wait for a task to exit."); + } + + // Add an event handler for the process exit event + var tcs = new TaskCompletionSource(); + process.Exited += (sender, args) => tcs.TrySetResult(true); + + // Return immediately if the process has already exited + if (process.HasExitedSafe()) + { + return true; + } + + // Add an additional timeout then await + using (var cancelTokenSource = new CancellationTokenSource(Math.Max(0, timeMs))) + using (var cancelRegistration = cancelTokenSource.Token.Register(() => tcs.TrySetResult(process.HasExitedSafe()))) + { + return await tcs.Task.ConfigureAwait(false); + } + } + } +} diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 4123f0203a..dbb7dea073 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -13,7 +13,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.MediaEncoding.Probing; using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Globalization; @@ -22,6 +21,8 @@ using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Configuration; +using System.Diagnostics; +using MediaBrowser.Model.Diagnostics; namespace MediaBrowser.MediaEncoding.Encoder { @@ -362,7 +363,7 @@ namespace MediaBrowser.MediaEncoding.Encoder : "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_format"; args = string.Format(args, probeSizeArgument, inputPath).Trim(); - var process = _processFactory.Create(new ProcessOptions + var process = _processFactory.Create(new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -374,10 +375,10 @@ namespace MediaBrowser.MediaEncoding.Encoder Arguments = args, - IsHidden = true, + WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, - EnableRaisingEvents = true }); + process.EnableRaisingEvents = true; if (forceEnableLogging) { @@ -571,16 +572,16 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - var process = _processFactory.Create(new ProcessOptions + var process = _processFactory.Create(new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, FileName = _ffmpegPath, Arguments = args, - IsHidden = true, + WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, - EnableRaisingEvents = true }); + process.EnableRaisingEvents = true; _logger.LogDebug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -700,16 +701,16 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - var process = _processFactory.Create(new ProcessOptions + var process = _processFactory.Create(new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, FileName = _ffmpegPath, Arguments = args, - IsHidden = true, - ErrorDialog = false, - EnableRaisingEvents = true + WindowStyle = ProcessWindowStyle.Hidden, + ErrorDialog = false }); + process.EnableRaisingEvents = true; _logger.LogInformation(process.StartInfo.FileName + " " + process.StartInfo.Arguments); @@ -949,14 +950,14 @@ namespace MediaBrowser.MediaEncoding.Encoder private bool _disposed = false; - public ProcessWrapper(IProcess process, MediaEncoder mediaEncoder) + public ProcessWrapper(Process process, MediaEncoder mediaEncoder) { Process = process; _mediaEncoder = mediaEncoder; Process.Exited += OnProcessExited; } - public IProcess Process { get; } + public Process Process { get; } public bool HasExited { get; private set; } @@ -964,7 +965,7 @@ namespace MediaBrowser.MediaEncoding.Encoder void OnProcessExited(object sender, EventArgs e) { - var process = (IProcess)sender; + var process = (Process)sender; HasExited = true; @@ -979,7 +980,7 @@ namespace MediaBrowser.MediaEncoding.Encoder DisposeProcess(process); } - private void DisposeProcess(IProcess process) + private void DisposeProcess(Process process) { lock (_mediaEncoder._runningProcessesLock) { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 6284e0fd9e..50ff834c62 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Concurrent; +using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -429,14 +430,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles encodingParam = " -sub_charenc " + encodingParam; } - var process = _processFactory.Create(new ProcessOptions + var process = _processFactory.Create(new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, FileName = _mediaEncoder.EncoderPath, Arguments = string.Format("{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath), - EnableRaisingEvents = true, - IsHidden = true, + WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false }); @@ -453,6 +453,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw; } + process.EnableRaisingEvents = true; var ranToCompletion = await process.WaitForExitAsync(300000).ConfigureAwait(false); if (!ranToCompletion) @@ -578,14 +579,13 @@ namespace MediaBrowser.MediaEncoding.Subtitles outputCodec, outputPath); - var process = _processFactory.Create(new ProcessOptions + var process = _processFactory.Create(new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, - EnableRaisingEvents = true, FileName = _mediaEncoder.EncoderPath, Arguments = processArgs, - IsHidden = true, + WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false }); @@ -602,6 +602,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw; } + process.EnableRaisingEvents = true; var ranToCompletion = await process.WaitForExitAsync(300000).ConfigureAwait(false); if (!ranToCompletion) diff --git a/MediaBrowser.Model/Diagnostics/IProcess.cs b/MediaBrowser.Model/Diagnostics/IProcess.cs deleted file mode 100644 index 514d1e7379..0000000000 --- a/MediaBrowser.Model/Diagnostics/IProcess.cs +++ /dev/null @@ -1,23 +0,0 @@ -#pragma warning disable CS1591 - -using System; -using System.IO; -using System.Threading.Tasks; - -namespace MediaBrowser.Model.Diagnostics -{ - public interface IProcess : IDisposable - { - 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..d95227797c 100644 --- a/MediaBrowser.Model/Diagnostics/IProcessFactory.cs +++ b/MediaBrowser.Model/Diagnostics/IProcessFactory.cs @@ -1,24 +1,11 @@ #pragma warning disable CS1591 +using System.Diagnostics; + namespace MediaBrowser.Model.Diagnostics { public interface IProcessFactory { - IProcess Create(ProcessOptions options); - } - - 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; } + Process Create(ProcessStartInfo options); } } From b947d98266371de7c9fd081e2038f53b3c67e859 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 00:45:48 +0100 Subject: [PATCH 0062/1003] Delete unnecessary ProcessFactory abstraction --- .../ApplicationHost.cs | 20 +++------- .../Diagnostics/ProcessFactory.cs | 15 ------- .../LiveTv/EmbyTV/EmbyTV.cs | 14 +++---- .../LiveTv/EmbyTV/EncodedRecorder.cs | 40 +++++++++---------- .../Encoder/MediaEncoder.cs | 22 +++++----- .../Subtitles/SubtitleEncoder.cs | 18 ++++----- .../Diagnostics/IProcessFactory.cs | 11 ----- 7 files changed, 44 insertions(+), 96 deletions(-) delete mode 100644 Emby.Server.Implementations/Diagnostics/ProcessFactory.cs delete mode 100644 MediaBrowser.Model/Diagnostics/IProcessFactory.cs diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index bc637b02f1..f6c08bba8d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -30,7 +30,6 @@ using Emby.Server.Implementations.Configuration; using Emby.Server.Implementations.Cryptography; using Emby.Server.Implementations.Data; using Emby.Server.Implementations.Devices; -using Emby.Server.Implementations.Diagnostics; using Emby.Server.Implementations.Dto; using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.HttpServer.Security; @@ -85,7 +84,6 @@ using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.Model.Activity; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Cryptography; -using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Events; using MediaBrowser.Model.Globalization; @@ -336,8 +334,6 @@ namespace Emby.Server.Implementations internal IImageEncoder ImageEncoder { get; private set; } - protected IProcessFactory ProcessFactory { get; private set; } - protected readonly IXmlSerializer XmlSerializer; protected ISocketFactory SocketFactory { get; private set; } @@ -685,9 +681,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton(XmlSerializer); - ProcessFactory = new ProcessFactory(); - serviceCollection.AddSingleton(ProcessFactory); - serviceCollection.AddSingleton(typeof(IStreamHelper), typeof(StreamHelper)); var cryptoProvider = new CryptographyProvider(); @@ -748,7 +741,6 @@ namespace Emby.Server.Implementations LoggerFactory.CreateLogger(), ServerConfigurationManager, FileSystemManager, - ProcessFactory, LocalizationManager, () => SubtitleEncoder, startupConfig, @@ -868,8 +860,7 @@ namespace Emby.Server.Implementations FileSystemManager, MediaEncoder, HttpClient, - MediaSourceManager, - ProcessFactory); + MediaSourceManager); serviceCollection.AddSingleton(SubtitleEncoder); serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager)); @@ -1727,15 +1718,14 @@ namespace Emby.Server.Implementations throw new NotSupportedException(); } - var process = ProcessFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { FileName = url, UseShellExecute = true, ErrorDialog = false - }); - - process.EnableRaisingEvents = true; - process.Exited += (sender, args) => ((Process)sender).Dispose(); ; + }; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; + process.Exited += (sender, args) => ((Process)sender).Dispose(); try { diff --git a/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs b/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs deleted file mode 100644 index 00172e17a6..0000000000 --- a/Emby.Server.Implementations/Diagnostics/ProcessFactory.cs +++ /dev/null @@ -1,15 +0,0 @@ -#pragma warning disable CS1591 - -using System.Diagnostics; -using MediaBrowser.Model.Diagnostics; - -namespace Emby.Server.Implementations.Diagnostics -{ - public class ProcessFactory : IProcessFactory - { - public Process Create(ProcessStartInfo startInfo) - { - return new Process { StartInfo = startInfo }; - } - } -} diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 0f54022c8e..e2ca0986bb 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -26,7 +26,6 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Events; @@ -62,7 +61,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private readonly ILibraryManager _libraryManager; private readonly IProviderManager _providerManager; private readonly IMediaEncoder _mediaEncoder; - private readonly IProcessFactory _processFactory; private readonly IMediaSourceManager _mediaSourceManager; private readonly IStreamHelper _streamHelper; @@ -89,8 +87,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV ILibraryManager libraryManager, ILibraryMonitor libraryMonitor, IProviderManager providerManager, - IMediaEncoder mediaEncoder, - IProcessFactory processFactory) + IMediaEncoder mediaEncoder) { Current = this; @@ -103,7 +100,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV _libraryMonitor = libraryMonitor; _providerManager = providerManager; _mediaEncoder = mediaEncoder; - _processFactory = processFactory; _liveTvManager = (LiveTvManager)liveTvManager; _jsonSerializer = jsonSerializer; _mediaSourceManager = mediaSourceManager; @@ -1663,7 +1659,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { if (mediaSource.RequiresLooping || !(mediaSource.Container ?? string.Empty).EndsWith("ts", StringComparison.OrdinalIgnoreCase) || (mediaSource.Protocol != MediaProtocol.File && mediaSource.Protocol != MediaProtocol.Http)) { - return new EncodedRecorder(_logger, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _processFactory, _config); + return new EncodedRecorder(_logger, _mediaEncoder, _config.ApplicationPaths, _jsonSerializer, _config); } return new DirectRecorder(_logger, _httpClient, _streamHelper); @@ -1684,7 +1680,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV try { - var process = _processFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { Arguments = GetPostProcessArguments(path, options.RecordingPostProcessorArguments), CreateNoWindow = true, @@ -1692,11 +1688,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV FileName = options.RecordingPostProcessor, WindowStyle = ProcessWindowStyle.Hidden, UseShellExecute = false - }); + }; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; _logger.LogInformation("Running recording post processor {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - process.EnableRaisingEvents = true; process.Exited += Process_Exited; process.Start(); } diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 3591384de1..55d1f810be 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -15,7 +15,6 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; -using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dto; using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; @@ -32,7 +31,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV private Stream _logFileStream; private string _targetPath; private Process _process; - private readonly IProcessFactory _processFactory; private readonly IJsonSerializer _json; private readonly TaskCompletionSource _taskCompletionSource = new TaskCompletionSource(); private readonly IServerConfigurationManager _config; @@ -42,14 +40,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV IMediaEncoder mediaEncoder, IServerApplicationPaths appPaths, IJsonSerializer json, - IProcessFactory processFactory, IServerConfigurationManager config) { _logger = logger; _mediaEncoder = mediaEncoder; _appPaths = appPaths; _json = json; - _processFactory = processFactory; _config = config; } @@ -81,7 +77,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV _targetPath = targetFile; Directory.CreateDirectory(Path.GetDirectoryName(targetFile)); - _process = _processFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -94,7 +90,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false - }); + }; + _process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; var commandLineLogMessage = _process.StartInfo.FileName + " " + _process.StartInfo.Arguments; _logger.LogInformation(commandLineLogMessage); @@ -108,7 +105,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(_json.SerializeToString(mediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine); _logFileStream.Write(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length); - _process.EnableRaisingEvents = true; _process.Exited += (sender, args) => OnFfMpegProcessExited(_process, inputFile); _process.Start(); @@ -297,24 +293,24 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV _hasExited = true; _logFileStream?.Dispose(); - _logFileStream = null; + _logFileStream = null; - var exitCode = process.ExitCode; + var exitCode = process.ExitCode; - _logger.LogInformation("FFMpeg recording exited with code {ExitCode} for {Path}", exitCode, _targetPath); + _logger.LogInformation("FFMpeg recording exited with code {ExitCode} for {Path}", exitCode, _targetPath); - if (exitCode == 0) - { - _taskCompletionSource.TrySetResult(true); - } - else - { - _taskCompletionSource.TrySetException( - new Exception( - string.Format( - CultureInfo.InvariantCulture, - "Recording for {0} failed. Exit code {1}", - _targetPath, + if (exitCode == 0) + { + _taskCompletionSource.TrySetResult(true); + } + else + { + _taskCompletionSource.TrySetException( + new Exception( + string.Format( + CultureInfo.InvariantCulture, + "Recording for {0} failed. Exit code {1}", + _targetPath, exitCode))); } } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index dbb7dea073..62a6c69ca5 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -22,7 +22,6 @@ using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Configuration; using System.Diagnostics; -using MediaBrowser.Model.Diagnostics; namespace MediaBrowser.MediaEncoding.Encoder { @@ -39,7 +38,6 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly ILogger _logger; private readonly IServerConfigurationManager _configurationManager; private readonly IFileSystem _fileSystem; - private readonly IProcessFactory _processFactory; private readonly ILocalizationManager _localization; private readonly Func _subtitleEncoder; private readonly IConfiguration _configuration; @@ -59,7 +57,6 @@ namespace MediaBrowser.MediaEncoding.Encoder ILogger logger, IServerConfigurationManager configurationManager, IFileSystem fileSystem, - IProcessFactory processFactory, ILocalizationManager localization, Func subtitleEncoder, IConfiguration configuration, @@ -68,7 +65,6 @@ namespace MediaBrowser.MediaEncoding.Encoder _logger = logger; _configurationManager = configurationManager; _fileSystem = fileSystem; - _processFactory = processFactory; _localization = localization; _startupOptionFFmpegPath = startupOptionsFFmpegPath; _subtitleEncoder = subtitleEncoder; @@ -363,7 +359,7 @@ namespace MediaBrowser.MediaEncoding.Encoder : "{0} -i {1} -threads 0 -v warning -print_format json -show_streams -show_format"; args = string.Format(args, probeSizeArgument, inputPath).Trim(); - var process = _processFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -377,8 +373,8 @@ namespace MediaBrowser.MediaEncoding.Encoder WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, - }); - process.EnableRaisingEvents = true; + }; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; if (forceEnableLogging) { @@ -572,7 +568,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - var process = _processFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -580,8 +576,8 @@ namespace MediaBrowser.MediaEncoding.Encoder Arguments = args, WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, - }); - process.EnableRaisingEvents = true; + }; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; _logger.LogDebug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -701,7 +697,7 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - var process = _processFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -709,8 +705,8 @@ namespace MediaBrowser.MediaEncoding.Encoder Arguments = args, WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false - }); - process.EnableRaisingEvents = true; + }; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; _logger.LogInformation(process.StartInfo.FileName + " " + process.StartInfo.Arguments); diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 50ff834c62..e2be2ea57c 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -13,7 +13,6 @@ using MediaBrowser.Common.Net; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Diagnostics; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; @@ -32,7 +31,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles private readonly IMediaEncoder _mediaEncoder; private readonly IHttpClient _httpClient; private readonly IMediaSourceManager _mediaSourceManager; - private readonly IProcessFactory _processFactory; public SubtitleEncoder( ILibraryManager libraryManager, @@ -41,8 +39,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles IFileSystem fileSystem, IMediaEncoder mediaEncoder, IHttpClient httpClient, - IMediaSourceManager mediaSourceManager, - IProcessFactory processFactory) + IMediaSourceManager mediaSourceManager) { _libraryManager = libraryManager; _logger = logger; @@ -51,7 +48,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles _mediaEncoder = mediaEncoder; _httpClient = httpClient; _mediaSourceManager = mediaSourceManager; - _processFactory = processFactory; } private string SubtitleCachePath => Path.Combine(_appPaths.DataPath, "subtitles"); @@ -430,7 +426,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles encodingParam = " -sub_charenc " + encodingParam; } - var process = _processFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -438,7 +434,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles Arguments = string.Format("{0} -i \"{1}\" -c:s srt \"{2}\"", encodingParam, inputPath, outputPath), WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false - }); + }; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; _logger.LogInformation("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -453,7 +450,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw; } - process.EnableRaisingEvents = true; var ranToCompletion = await process.WaitForExitAsync(300000).ConfigureAwait(false); if (!ranToCompletion) @@ -579,7 +575,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles outputCodec, outputPath); - var process = _processFactory.Create(new ProcessStartInfo + var processStartInfo = new ProcessStartInfo { CreateNoWindow = true, UseShellExecute = false, @@ -587,7 +583,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles Arguments = processArgs, WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false - }); + }; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -602,7 +599,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw; } - process.EnableRaisingEvents = true; var ranToCompletion = await process.WaitForExitAsync(300000).ConfigureAwait(false); if (!ranToCompletion) diff --git a/MediaBrowser.Model/Diagnostics/IProcessFactory.cs b/MediaBrowser.Model/Diagnostics/IProcessFactory.cs deleted file mode 100644 index d95227797c..0000000000 --- a/MediaBrowser.Model/Diagnostics/IProcessFactory.cs +++ /dev/null @@ -1,11 +0,0 @@ -#pragma warning disable CS1591 - -using System.Diagnostics; - -namespace MediaBrowser.Model.Diagnostics -{ - public interface IProcessFactory - { - Process Create(ProcessStartInfo options); - } -} From 7447ea89609fe79be3c5d282a23fc6d7d2bddd66 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 00:49:22 +0100 Subject: [PATCH 0063/1003] Make sure Process objects are all disposed correctly --- .../LiveTv/EmbyTV/EncodedRecorder.cs | 13 ++++++++++--- .../Subtitles/SubtitleEncoder.cs | 6 ++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs index 55d1f810be..46fb47b7b9 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs @@ -290,9 +290,11 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV /// private void OnFfMpegProcessExited(Process process, string inputFile) { - _hasExited = true; + try + { + _hasExited = true; - _logFileStream?.Dispose(); + _logFileStream?.Dispose(); _logFileStream = null; var exitCode = process.ExitCode; @@ -311,7 +313,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV CultureInfo.InvariantCulture, "Recording for {0} failed. Exit code {1}", _targetPath, - exitCode))); + exitCode))); + } + } + finally + { + process.Dispose(); } } diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index e2be2ea57c..1736d79cf2 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -436,6 +436,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles ErrorDialog = false }; var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; + process.Exited += (sender, args) => ((Process)sender).Dispose(); _logger.LogInformation("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -468,8 +469,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles var exitCode = ranToCompletion ? process.ExitCode : -1; - process.Dispose(); - var failed = false; if (exitCode == -1) @@ -585,6 +584,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles ErrorDialog = false }; var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; + process.Exited += (sender, args) => ((Process)sender).Dispose(); _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); @@ -617,8 +617,6 @@ namespace MediaBrowser.MediaEncoding.Subtitles var exitCode = ranToCompletion ? process.ExitCode : -1; - process.Dispose(); - var failed = false; if (exitCode == -1) From 97c36d11d4e52a8f33d48e382467b6c6068bb6ad Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 01:09:09 +0100 Subject: [PATCH 0064/1003] Use a TimeSpan instead of ms and support providing a custom CancellationToken --- .../Extensions/ProcessExtensions.cs | 23 +++++++++++++++---- .../Encoder/MediaEncoder.cs | 4 ++-- .../Subtitles/SubtitleEncoder.cs | 4 ++-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/MediaBrowser.Common/Extensions/ProcessExtensions.cs b/MediaBrowser.Common/Extensions/ProcessExtensions.cs index 9fa0efdff8..938ced1067 100644 --- a/MediaBrowser.Common/Extensions/ProcessExtensions.cs +++ b/MediaBrowser.Common/Extensions/ProcessExtensions.cs @@ -36,9 +36,23 @@ namespace MediaBrowser.Common.Extensions /// Asynchronously wait for the process to exit. /// /// The process to wait for. - /// A timeout, in milliseconds, after which to stop waiting for the task. + /// The duration to wait before cancelling waiting for the task. /// True if the task exited normally, false if the timeout elapsed before the process exited. - public static async Task WaitForExitAsync(this Process process, int timeMs) + public static async Task WaitForExitAsync(this Process process, TimeSpan timeout) + { + using (var cancelTokenSource = new CancellationTokenSource(timeout)) + { + return await WaitForExitAsync(process, cancelTokenSource.Token); + } + } + + /// + /// Asynchronously wait for the process to exit. + /// + /// The process to wait for. + /// A to observe while waiting for the process to exit. + /// True if the task exited normally, false if cancelled before the process exited. + public static async Task WaitForExitAsync(this Process process, CancellationToken cancelToken) { if (!process.EnableRaisingEvents) { @@ -55,9 +69,8 @@ namespace MediaBrowser.Common.Extensions return true; } - // Add an additional timeout then await - using (var cancelTokenSource = new CancellationTokenSource(Math.Max(0, timeMs))) - using (var cancelRegistration = cancelTokenSource.Token.Register(() => tcs.TrySetResult(process.HasExitedSafe()))) + // Register with the cancellation token then await + using (var cancelRegistration = cancelToken.Register(() => tcs.TrySetResult(process.HasExitedSafe()))) { return await tcs.Task.ConfigureAwait(false); } diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 62a6c69ca5..855b1c7547 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -596,7 +596,7 @@ namespace MediaBrowser.MediaEncoding.Encoder timeoutMs = DefaultImageExtractionTimeout; } - ranToCompletion = await process.WaitForExitAsync(timeoutMs).ConfigureAwait(false); + ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMilliseconds(timeoutMs)).ConfigureAwait(false); if (!ranToCompletion) { @@ -729,7 +729,7 @@ namespace MediaBrowser.MediaEncoding.Encoder while (isResponsive) { - if (await process.WaitForExitAsync(30000).ConfigureAwait(false)) + if (await process.WaitForExitAsync(TimeSpan.FromSeconds(30)).ConfigureAwait(false)) { ranToCompletion = true; break; diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 1736d79cf2..f1f0bfeb15 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -451,7 +451,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw; } - var ranToCompletion = await process.WaitForExitAsync(300000).ConfigureAwait(false); + var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(5)).ConfigureAwait(false); if (!ranToCompletion) { @@ -599,7 +599,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw; } - var ranToCompletion = await process.WaitForExitAsync(300000).ConfigureAwait(false); + var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(5)).ConfigureAwait(false); if (!ranToCompletion) { From 48bbcbb426b15724ccae05c71d418c8ce80cfb68 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 01:09:25 +0100 Subject: [PATCH 0065/1003] Use WaitForExitAsync extension method in AttachmentExtractor --- .../Attachments/AttachmentExtractor.cs | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs index c530c9fd81..cb1d8d7bb8 100644 --- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs +++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs @@ -166,19 +166,15 @@ namespace MediaBrowser.MediaEncoding.Attachments }; var process = new Process { - StartInfo = startInfo + StartInfo = startInfo, + EnableRaisingEvents = true }; _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); process.Start(); - var processTcs = new TaskCompletionSource(); - process.EnableRaisingEvents = true; - process.Exited += (sender, args) => processTcs.TrySetResult(true); - var unregister = cancellationToken.Register(() => processTcs.TrySetResult(process.HasExited)); - var ranToCompletion = await processTcs.Task.ConfigureAwait(false); - unregister.Dispose(); + var ranToCompletion = await process.WaitForExitAsync(cancellationToken); if (!ranToCompletion) { From 1c13be085fbc30ac6c5efa893f415fa0d06d557f Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 01:28:24 +0100 Subject: [PATCH 0066/1003] Make HasExitedSafe() private --- .../Extensions/ProcessExtensions.cs | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/MediaBrowser.Common/Extensions/ProcessExtensions.cs b/MediaBrowser.Common/Extensions/ProcessExtensions.cs index 938ced1067..525475ba5f 100644 --- a/MediaBrowser.Common/Extensions/ProcessExtensions.cs +++ b/MediaBrowser.Common/Extensions/ProcessExtensions.cs @@ -10,28 +10,6 @@ namespace MediaBrowser.Common.Extensions /// public static class ProcessExtensions { - /// - /// Gets a value indicating whether the associated process has been terminated using - /// . This is safe to call even if there is no operating system process - /// associated with the . - /// - /// The process to check the exit status for. - /// - /// True if the operating system process referenced by the component has - /// terminated, or if there is no associated operating system process; otherwise, false. - /// - public static bool HasExitedSafe(this Process process) - { - try - { - return process.HasExited; - } - catch (InvalidOperationException) - { - return true; - } - } - /// /// Asynchronously wait for the process to exit. /// @@ -75,5 +53,27 @@ namespace MediaBrowser.Common.Extensions return await tcs.Task.ConfigureAwait(false); } } + + /// + /// Gets a value indicating whether the associated process has been terminated using + /// . This is safe to call even if there is no operating system process + /// associated with the . + /// + /// The process to check the exit status for. + /// + /// True if the operating system process referenced by the component has + /// terminated, or if there is no associated operating system process; otherwise, false. + /// + private static bool HasExitedSafe(this Process process) + { + try + { + return process.HasExited; + } + catch (InvalidOperationException) + { + return true; + } + } } } From d705931e816db63b560efad51b8d0b79564aa260 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 01:42:28 +0100 Subject: [PATCH 0067/1003] Dispose of process correctly in AttachmentExtractor --- .../Attachments/AttachmentExtractor.cs | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs index cb1d8d7bb8..d976347317 100644 --- a/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs +++ b/MediaBrowser.MediaEncoding/Attachments/AttachmentExtractor.cs @@ -164,34 +164,32 @@ namespace MediaBrowser.MediaEncoding.Attachments WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false }; - var process = new Process - { - StartInfo = startInfo, - EnableRaisingEvents = true - }; - _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); + int exitCode; - process.Start(); + using (var process = new Process { StartInfo = startInfo, EnableRaisingEvents = true }) + { + _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); - var ranToCompletion = await process.WaitForExitAsync(cancellationToken); + process.Start(); - if (!ranToCompletion) - { - try - { - _logger.LogWarning("Killing ffmpeg attachment extraction process"); - process.Kill(); - } - catch (Exception ex) + var ranToCompletion = await process.WaitForExitAsync(cancellationToken); + + if (!ranToCompletion) { - _logger.LogError(ex, "Error killing attachment extraction process"); + try + { + _logger.LogWarning("Killing ffmpeg attachment extraction process"); + process.Kill(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error killing attachment extraction process"); + } } - } - - var exitCode = ranToCompletion ? process.ExitCode : -1; - process.Dispose(); + exitCode = ranToCompletion ? process.ExitCode : -1; + } var failed = false; From 1f5caa46c53dde25ecf4482715333c049cb7e085 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Fri, 27 Mar 2020 01:53:08 +0100 Subject: [PATCH 0068/1003] Fix some more issues with disposing Process instances --- .../Encoder/MediaEncoder.cs | 8 +- .../Subtitles/SubtitleEncoder.cs | 94 ++++++++++--------- 2 files changed, 54 insertions(+), 48 deletions(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 855b1c7547..b3a45991e7 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -577,10 +577,10 @@ namespace MediaBrowser.MediaEncoding.Encoder WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false, }; - var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; - _logger.LogDebug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + _logger.LogDebug("{0} {1}", processStartInfo.FileName, processStartInfo.Arguments); + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; using (var processWrapper = new ProcessWrapper(process, this)) { bool ranToCompletion; @@ -706,14 +706,14 @@ namespace MediaBrowser.MediaEncoding.Encoder WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false }; - var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; - _logger.LogInformation(process.StartInfo.FileName + " " + process.StartInfo.Arguments); + _logger.LogInformation(processStartInfo.FileName + " " + processStartInfo.Arguments); await _thumbnailResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); bool ranToCompletion = false; + var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; using (var processWrapper = new ProcessWrapper(process, this)) { try diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index f1f0bfeb15..a6982be5b6 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -435,39 +435,42 @@ namespace MediaBrowser.MediaEncoding.Subtitles WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false }; - var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; - process.Exited += (sender, args) => ((Process)sender).Dispose(); - _logger.LogInformation("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + int exitCode; - try - { - process.Start(); - } - catch (Exception ex) + using (var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }) { - _logger.LogError(ex, "Error starting ffmpeg"); - - throw; - } + _logger.LogInformation("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(5)).ConfigureAwait(false); - - if (!ranToCompletion) - { try { - _logger.LogInformation("Killing ffmpeg subtitle conversion process"); - - process.Kill(); + process.Start(); } catch (Exception ex) { - _logger.LogError(ex, "Error killing subtitle conversion process"); + _logger.LogError(ex, "Error starting ffmpeg"); + + throw; } - } - var exitCode = ranToCompletion ? process.ExitCode : -1; + var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(5)).ConfigureAwait(false); + + if (!ranToCompletion) + { + try + { + _logger.LogInformation("Killing ffmpeg subtitle conversion process"); + + process.Kill(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error killing subtitle conversion process"); + } + } + + exitCode = ranToCompletion ? process.ExitCode : -1; + } var failed = false; @@ -583,39 +586,42 @@ namespace MediaBrowser.MediaEncoding.Subtitles WindowStyle = ProcessWindowStyle.Hidden, ErrorDialog = false }; - var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }; - process.Exited += (sender, args) => ((Process)sender).Dispose(); - _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); + int exitCode; - try - { - process.Start(); - } - catch (Exception ex) + using (var process = new Process { StartInfo = processStartInfo, EnableRaisingEvents = true }) { - _logger.LogError(ex, "Error starting ffmpeg"); - - throw; - } + _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); - var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(5)).ConfigureAwait(false); - - if (!ranToCompletion) - { try { - _logger.LogWarning("Killing ffmpeg subtitle extraction process"); - - process.Kill(); + process.Start(); } catch (Exception ex) { - _logger.LogError(ex, "Error killing subtitle extraction process"); + _logger.LogError(ex, "Error starting ffmpeg"); + + throw; } - } - var exitCode = ranToCompletion ? process.ExitCode : -1; + var ranToCompletion = await process.WaitForExitAsync(TimeSpan.FromMinutes(5)).ConfigureAwait(false); + + if (!ranToCompletion) + { + try + { + _logger.LogWarning("Killing ffmpeg subtitle extraction process"); + + process.Kill(); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error killing subtitle extraction process"); + } + } + + exitCode = ranToCompletion ? process.ExitCode : -1; + } var failed = false; From 5fcbedc194a7a8a7a8026a69b44f8192120d14e1 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 28 Mar 2020 13:40:56 +0100 Subject: [PATCH 0069/1003] Display extras with an unknown type --- Emby.Server.Implementations/Dto/DtoService.cs | 21 ++----- .../UserLibrary/UserLibraryService.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 56 +++++++++++++++++-- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index 65711e89d8..a10e17f6ad 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -1056,30 +1056,19 @@ namespace Emby.Server.Implementations.Dto if (options.ContainsField(ItemFields.SpecialFeatureCount)) { - if (allExtras == null) - { - allExtras = item.GetExtras().ToArray(); - } - - dto.SpecialFeatureCount = allExtras.Count(i => i.ExtraType.HasValue && BaseItem.DisplayExtraTypes.Contains(i.ExtraType.Value)); + allExtras = item.GetExtras().ToArray(); + dto.SpecialFeatureCount = allExtras.Count(i => i.HasExtraType(BaseItem.DisplayExtraTypes, true)); } if (options.ContainsField(ItemFields.LocalTrailerCount)) { - int trailerCount = 0; - if (allExtras == null) - { - allExtras = item.GetExtras().ToArray(); - } - - trailerCount += allExtras.Count(i => i.ExtraType.HasValue && i.ExtraType.Value == ExtraType.Trailer); + allExtras = allExtras ?? item.GetExtras().ToArray(); + dto.LocalTrailerCount = allExtras.Count(i => i.HasExtraType(new[] { ExtraType.Trailer }, false)); if (item is IHasTrailers hasTrailers) { - trailerCount += hasTrailers.GetTrailerCount(); + dto.LocalTrailerCount += hasTrailers.GetTrailerCount(); } - - dto.LocalTrailerCount = trailerCount; } // Add EpisodeInfo diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 2ec08f5787..a55b0253ac 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -380,7 +380,7 @@ namespace MediaBrowser.Api.UserLibrary var dtoOptions = GetDtoOptions(_authContext, request); - var dtosExtras = item.GetExtras(new[] { ExtraType.Trailer }) + var dtosExtras = item.GetExtras(new[] { ExtraType.Trailer }, false) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)) .ToArray(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index a9ec19e2fd..2a941a684a 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2878,14 +2878,30 @@ namespace MediaBrowser.Controller.Entities /// The remote trailers. public IReadOnlyList RemoteTrailers { get; set; } + /// + /// Get all extras associated with this item, sorted by . + /// + /// An enumerable containing the items. public IEnumerable GetExtras() { - return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i != null).OrderBy(i => i.SortName); + return ExtraIds + .Select(LibraryManager.GetItemById) + .Where(i => i != null) + .OrderBy(i => i.SortName); } - public IEnumerable GetExtras(IReadOnlyCollection extraTypes) + /// + /// Get all extras with specific types that are associated with this item. + /// + /// The types of extras to retrieve. + /// If true, include extras whose type could not be determined. + /// An enumerable containing the extras. + public IEnumerable GetExtras(IReadOnlyCollection extraTypes, bool includeUnknownTypes) { - return ExtraIds.Select(LibraryManager.GetItemById).Where(i => i?.ExtraType != null && extraTypes.Contains(i.ExtraType.Value)); + return ExtraIds + .Select(LibraryManager.GetItemById) + .Where(i => i != null) + .Where(i => i.HasExtraType(extraTypes, includeUnknownTypes)); } public IEnumerable GetTrailers() @@ -2896,9 +2912,27 @@ namespace MediaBrowser.Controller.Entities return Array.Empty(); } + /// + /// Get all extras associated with this item that should be displayed as "Special Features" in the UI. This is + /// all extras with either an unknown type, or a type contained in . + /// + /// An IEnumerable containing the extra items. public IEnumerable GetDisplayExtras() { - return GetExtras(DisplayExtraTypes); + return GetExtras(DisplayExtraTypes, true); + } + + /// + /// Check if this item is an extra with a type that matches a given set. + /// + /// The types of extras to match with. + /// If true, include extras whose type could not be determined. + /// True if this item matches, otherwise false. + public bool HasExtraType(IReadOnlyCollection extraTypes, bool includeUnknownTypes) + { + return + (includeUnknownTypes && (ExtraType == null || ExtraType == 0)) + || (ExtraType.HasValue && extraTypes.Contains(ExtraType.Value)); } public virtual bool IsHD => Height >= 720; @@ -2918,8 +2952,18 @@ namespace MediaBrowser.Controller.Entities return RunTimeTicks ?? 0; } - // Possible types of extra videos - public static readonly IReadOnlyCollection DisplayExtraTypes = new[] { Model.Entities.ExtraType.BehindTheScenes, Model.Entities.ExtraType.Clip, Model.Entities.ExtraType.DeletedScene, Model.Entities.ExtraType.Interview, Model.Entities.ExtraType.Sample, Model.Entities.ExtraType.Scene }; + /// + /// Extra types that should be counted and displayed as "Special Features" in the UI. + /// + public static readonly IReadOnlyCollection DisplayExtraTypes = new HashSet + { + Model.Entities.ExtraType.BehindTheScenes, + Model.Entities.ExtraType.Clip, + Model.Entities.ExtraType.DeletedScene, + Model.Entities.ExtraType.Interview, + Model.Entities.ExtraType.Sample, + Model.Entities.ExtraType.Scene + }; public virtual bool SupportsExternalTransfer => false; From ea306e8f6d28e4c4acb78ee7208508d329473414 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 28 Mar 2020 13:54:14 +0100 Subject: [PATCH 0070/1003] Do not assign an invalid value of zero to ExtraType --- MediaBrowser.Controller/Entities/BaseItem.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2a941a684a..66917e4428 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1327,8 +1327,9 @@ namespace MediaBrowser.Controller.Entities } // Use some hackery to get the extra type based on foldername - Enum.TryParse(extraFolderName.Replace(" ", ""), true, out ExtraType extraType); - item.ExtraType = extraType; + item.ExtraType = Enum.TryParse(extraFolderName.Replace(" ", ""), true, out ExtraType extraType) + ? extraType + : (ExtraType?)null; return item; From e266ad51c52763f11a2eab9ac86f638542a4ddb0 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 28 Mar 2020 14:17:33 +0100 Subject: [PATCH 0071/1003] Simplify logic; remove unnecessary methods --- Emby.Server.Implementations/Dto/DtoService.cs | 4 +-- .../UserLibrary/UserLibraryService.cs | 5 +-- MediaBrowser.Controller/Entities/BaseItem.cs | 32 +++---------------- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index a10e17f6ad..f8cf00cb3b 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -1057,13 +1057,13 @@ namespace Emby.Server.Implementations.Dto if (options.ContainsField(ItemFields.SpecialFeatureCount)) { allExtras = item.GetExtras().ToArray(); - dto.SpecialFeatureCount = allExtras.Count(i => i.HasExtraType(BaseItem.DisplayExtraTypes, true)); + dto.SpecialFeatureCount = allExtras.Count(i => BaseItem.DisplayExtraTypes.Contains(i.ExtraType)); } if (options.ContainsField(ItemFields.LocalTrailerCount)) { allExtras = allExtras ?? item.GetExtras().ToArray(); - dto.LocalTrailerCount = allExtras.Count(i => i.HasExtraType(new[] { ExtraType.Trailer }, false)); + dto.LocalTrailerCount = allExtras.Count(i => i.ExtraType == ExtraType.Trailer); if (item is IHasTrailers hasTrailers) { diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index a55b0253ac..21d2fc9923 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -361,7 +361,8 @@ namespace MediaBrowser.Api.UserLibrary var dtoOptions = GetDtoOptions(_authContext, request); - var dtos = item.GetDisplayExtras() + var dtos = item + .GetExtras(BaseItem.DisplayExtraTypes) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)); return dtos.ToArray(); @@ -380,7 +381,7 @@ namespace MediaBrowser.Api.UserLibrary var dtoOptions = GetDtoOptions(_authContext, request); - var dtosExtras = item.GetExtras(new[] { ExtraType.Trailer }, false) + var dtosExtras = item.GetExtras(new ExtraType?[] { ExtraType.Trailer }) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)) .ToArray(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 66917e4428..2424293fe1 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -2895,14 +2895,13 @@ namespace MediaBrowser.Controller.Entities /// Get all extras with specific types that are associated with this item. /// /// The types of extras to retrieve. - /// If true, include extras whose type could not be determined. /// An enumerable containing the extras. - public IEnumerable GetExtras(IReadOnlyCollection extraTypes, bool includeUnknownTypes) + public IEnumerable GetExtras(IReadOnlyCollection extraTypes) { return ExtraIds .Select(LibraryManager.GetItemById) .Where(i => i != null) - .Where(i => i.HasExtraType(extraTypes, includeUnknownTypes)); + .Where(i => extraTypes.Contains(i.ExtraType)); } public IEnumerable GetTrailers() @@ -2913,29 +2912,6 @@ namespace MediaBrowser.Controller.Entities return Array.Empty(); } - /// - /// Get all extras associated with this item that should be displayed as "Special Features" in the UI. This is - /// all extras with either an unknown type, or a type contained in . - /// - /// An IEnumerable containing the extra items. - public IEnumerable GetDisplayExtras() - { - return GetExtras(DisplayExtraTypes, true); - } - - /// - /// Check if this item is an extra with a type that matches a given set. - /// - /// The types of extras to match with. - /// If true, include extras whose type could not be determined. - /// True if this item matches, otherwise false. - public bool HasExtraType(IReadOnlyCollection extraTypes, bool includeUnknownTypes) - { - return - (includeUnknownTypes && (ExtraType == null || ExtraType == 0)) - || (ExtraType.HasValue && extraTypes.Contains(ExtraType.Value)); - } - public virtual bool IsHD => Height >= 720; public bool IsShortcut { get; set; } @@ -2956,8 +2932,10 @@ namespace MediaBrowser.Controller.Entities /// /// Extra types that should be counted and displayed as "Special Features" in the UI. /// - public static readonly IReadOnlyCollection DisplayExtraTypes = new HashSet + public static readonly IReadOnlyCollection DisplayExtraTypes = new HashSet { + null, + 0, Model.Entities.ExtraType.BehindTheScenes, Model.Entities.ExtraType.Clip, Model.Entities.ExtraType.DeletedScene, From 8094687b9c589038ce87879c51785cd63c8ef8ac Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 30 Mar 2020 02:40:06 -0400 Subject: [PATCH 0072/1003] 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 db2366066029fa8e261d308d9db845070c0b9ca4 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Mon, 30 Mar 2020 15:53:49 +0800 Subject: [PATCH 0073/1003] prefer to use libfdk_aac for better audio quality --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 5 +++++ MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs | 1 + 2 files changed, 6 insertions(+) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 342c764146..2037a27fa1 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -424,6 +424,11 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(codec, "aac", StringComparison.OrdinalIgnoreCase)) { + // Prefer to use libfdk_aac for better audio quality while using the custom build FFmpeg + if (_mediaEncoder.SupportsEncoder("libfdk_aac")) + { + return "libfdk_aac"; + } return "aac -strict experimental"; } diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index f5decdc0db..6e036d24c1 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -42,6 +42,7 @@ namespace MediaBrowser.MediaEncoding.Encoder "libvpx", "libvpx-vp9", "aac", + "libfdk_aac", "libmp3lame", "libopus", "libvorbis", From 49da8766d8aac23ab6f6c64a4fee1885b04918f3 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 30 Mar 2020 02:43:13 -0400 Subject: [PATCH 0074/1003] 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 025888204de529d21bc54b68de9d19fa4ab5c56b Mon Sep 17 00:00:00 2001 From: PrplHaz4 Date: Mon, 30 Mar 2020 17:14:59 -0400 Subject: [PATCH 0075/1003] Fix permission setting on Channels Currently, permission settings on Channels are not taken into account prior to returning `{UserName} is not permitted to access Library {ItemName}.`. Whether or not a user can see items within the Channel is solely dependent on `EnableAllFolders`, so you cannot view a plugin's Channels unless you can also see ALL libraries. This PR enables does two things for Channel-providing Plugins: 1. Fixes functionality of "EnableAllChannels" 2. Allows users with Channel permissions to access all folders within that Channel I'm not 100% sure on 2 but I wasn't able to see an obvious way to propagate permissions downward into specific Folders inside a Channel. I tested on a fairly simple library with two channel-providing plugins (ServerWMC, LazyMan) and it seems to work, but this behavior should also be tested by someone with more content/collections. --- MediaBrowser.Api/UserLibrary/ItemsService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index c7b5051712..46082cdc3f 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -214,6 +214,10 @@ namespace MediaBrowser.Api.UserLibrary } bool isInEnabledFolder = user.Policy.EnabledFolders.Any(i => new Guid(i) == item.Id); + + // Assume all folders inside an EnabledChannel are enabled + isInEnabledFolder = isInEnabledFolder || user.Policy.EnabledChannels.Any(i => new Guid(i) == item.Id); + var collectionFolders = _libraryManager.GetCollectionFolders(item); foreach (var collectionFolder in collectionFolders) { @@ -225,7 +229,7 @@ namespace MediaBrowser.Api.UserLibrary } } - if (!(item is UserRootFolder) && !user.Policy.EnableAllFolders && !isInEnabledFolder) + if (!(item is UserRootFolder) && !user.Policy.EnableAllFolders && !isInEnabledFolder && !user.Policy.EnableAllChannels) { Logger.LogWarning("{UserName} is not permitted to access Library {ItemName}.", user.Name, item.Name); return new QueryResult From cf98a1fbc7be2cb58d348225ae450dddae0038d3 Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Wed, 1 Apr 2020 00:22:10 +0800 Subject: [PATCH 0076/1003] update as per suggestion Co-Authored-By: Vasily --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 2037a27fa1..8845ec0057 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -424,7 +424,7 @@ namespace MediaBrowser.Controller.MediaEncoding if (string.Equals(codec, "aac", StringComparison.OrdinalIgnoreCase)) { - // Prefer to use libfdk_aac for better audio quality while using the custom build FFmpeg + // Use libfdk_aac for better audio quality if using custom build of FFmpeg which has fdk_aac support if (_mediaEncoder.SupportsEncoder("libfdk_aac")) { return "libfdk_aac"; From ebb7590350bc50e65e6b2834de60671390a50ce9 Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Wed, 1 Apr 2020 07:48:29 +0800 Subject: [PATCH 0077/1003] update as per suggestion Co-Authored-By: Vasily --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 8845ec0057..2b9f513b56 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -429,7 +429,7 @@ namespace MediaBrowser.Controller.MediaEncoding { return "libfdk_aac"; } - return "aac -strict experimental"; + return "aac"; } if (string.Equals(codec, "mp3", StringComparison.OrdinalIgnoreCase)) From cc8294842a41478e7c22bcef39c0cfcc114f05a0 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Wed, 1 Apr 2020 18:10:29 +0200 Subject: [PATCH 0078/1003] Add ExtraType.Unknown enum value and use it instead of null --- Emby.Server.Implementations/Dto/DtoService.cs | 2 +- MediaBrowser.Api/UserLibrary/UserLibraryService.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 11 +++++------ MediaBrowser.Model/Entities/ExtraType.cs | 1 + 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs index f8cf00cb3b..67ecdb4ea7 100644 --- a/Emby.Server.Implementations/Dto/DtoService.cs +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -1057,7 +1057,7 @@ namespace Emby.Server.Implementations.Dto if (options.ContainsField(ItemFields.SpecialFeatureCount)) { allExtras = item.GetExtras().ToArray(); - dto.SpecialFeatureCount = allExtras.Count(i => BaseItem.DisplayExtraTypes.Contains(i.ExtraType)); + dto.SpecialFeatureCount = allExtras.Count(i => i.ExtraType.HasValue && BaseItem.DisplayExtraTypes.Contains(i.ExtraType.Value)); } if (options.ContainsField(ItemFields.LocalTrailerCount)) diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 21d2fc9923..4cd201c3b0 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -381,7 +381,7 @@ namespace MediaBrowser.Api.UserLibrary var dtoOptions = GetDtoOptions(_authContext, request); - var dtosExtras = item.GetExtras(new ExtraType?[] { ExtraType.Trailer }) + var dtosExtras = item.GetExtras(new ExtraType[] { ExtraType.Trailer }) .Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item)) .ToArray(); diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 2424293fe1..cfc80ac095 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -1329,7 +1329,7 @@ namespace MediaBrowser.Controller.Entities // Use some hackery to get the extra type based on foldername item.ExtraType = Enum.TryParse(extraFolderName.Replace(" ", ""), true, out ExtraType extraType) ? extraType - : (ExtraType?)null; + : Model.Entities.ExtraType.Unknown; return item; @@ -2896,12 +2896,12 @@ namespace MediaBrowser.Controller.Entities /// /// The types of extras to retrieve. /// An enumerable containing the extras. - public IEnumerable GetExtras(IReadOnlyCollection extraTypes) + public IEnumerable GetExtras(IReadOnlyCollection extraTypes) { return ExtraIds .Select(LibraryManager.GetItemById) .Where(i => i != null) - .Where(i => extraTypes.Contains(i.ExtraType)); + .Where(i => i.ExtraType.HasValue && extraTypes.Contains(i.ExtraType.Value)); } public IEnumerable GetTrailers() @@ -2932,10 +2932,9 @@ namespace MediaBrowser.Controller.Entities /// /// Extra types that should be counted and displayed as "Special Features" in the UI. /// - public static readonly IReadOnlyCollection DisplayExtraTypes = new HashSet + public static readonly IReadOnlyCollection DisplayExtraTypes = new HashSet { - null, - 0, + Model.Entities.ExtraType.Unknown, Model.Entities.ExtraType.BehindTheScenes, Model.Entities.ExtraType.Clip, Model.Entities.ExtraType.DeletedScene, diff --git a/MediaBrowser.Model/Entities/ExtraType.cs b/MediaBrowser.Model/Entities/ExtraType.cs index 857e92adbe..aca4bd2829 100644 --- a/MediaBrowser.Model/Entities/ExtraType.cs +++ b/MediaBrowser.Model/Entities/ExtraType.cs @@ -4,6 +4,7 @@ namespace MediaBrowser.Model.Entities { public enum ExtraType { + Unknown = 0, Clip = 1, Trailer = 2, BehindTheScenes = 3, From d9b78a1dc5f3cbabafc6393887762815a23e2bac Mon Sep 17 00:00:00 2001 From: Nyanmisaka Date: Thu, 2 Apr 2020 00:48:43 +0800 Subject: [PATCH 0079/1003] update as per suggestion Co-Authored-By: Bond-009 --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index 2b9f513b56..ecb028b3ae 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -429,6 +429,7 @@ namespace MediaBrowser.Controller.MediaEncoding { return "libfdk_aac"; } + return "aac"; } From 2e1ec2858a5bd2a03d8dd5fd0ae9f9c11487ed7f Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Wed, 1 Apr 2020 18:53:19 +0200 Subject: [PATCH 0080/1003] Match using directory names in ExtraResolver --- Emby.Naming/Common/NamingOptions.cs | 10 +++++++++- Emby.Naming/Video/ExtraResolver.cs | 9 +++++++++ Emby.Naming/Video/ExtraRuleType.cs | 13 +++++++++---- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/Emby.Naming/Common/NamingOptions.cs b/Emby.Naming/Common/NamingOptions.cs index 793847f84c..8ac33d3f55 100644 --- a/Emby.Naming/Common/NamingOptions.cs +++ b/Emby.Naming/Common/NamingOptions.cs @@ -505,7 +505,15 @@ namespace Emby.Naming.Common RuleType = ExtraRuleType.Suffix, Token = "-short", MediaType = MediaType.Video - } + }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.BehindTheScenes, Token = "behind the scenes" }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.DeletedScene, Token = "deleted scenes" }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.Interview, Token = "interviews" }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.Scene, Token = "scenes" }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.Sample, Token = "samples" }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.Clip, Token = "shorts" }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.Clip, Token = "featurettes" }, + new ExtraRule { RuleType = ExtraRuleType.DirectoryName, MediaType = MediaType.Video, ExtraType = ExtraType.Unknown, Token = "extras" }, }; Format3DRules = new[] diff --git a/Emby.Naming/Video/ExtraResolver.cs b/Emby.Naming/Video/ExtraResolver.cs index 42a5c88b31..fc0424faab 100644 --- a/Emby.Naming/Video/ExtraResolver.cs +++ b/Emby.Naming/Video/ExtraResolver.cs @@ -80,6 +80,15 @@ namespace Emby.Naming.Video result.Rule = rule; } } + else if (rule.RuleType == ExtraRuleType.DirectoryName) + { + var directoryName = Path.GetFileName(Path.GetDirectoryName(path)); + if (string.Equals(directoryName, rule.Token, StringComparison.OrdinalIgnoreCase)) + { + result.ExtraType = rule.ExtraType; + result.Rule = rule; + } + } return result; } diff --git a/Emby.Naming/Video/ExtraRuleType.cs b/Emby.Naming/Video/ExtraRuleType.cs index b021a04a31..0a304874d2 100644 --- a/Emby.Naming/Video/ExtraRuleType.cs +++ b/Emby.Naming/Video/ExtraRuleType.cs @@ -5,18 +5,23 @@ namespace Emby.Naming.Video public enum ExtraRuleType { /// - /// The suffix + /// Match against a suffix in the file name. /// Suffix = 0, /// - /// The filename + /// Match against the file name. /// Filename = 1, /// - /// The regex + /// Match against the a regex. /// - Regex = 2 + Regex = 2, + + /// + /// Match against the directory name of the file. + /// + DirectoryName = 3, } } From 34204046dd8304c6fbd06c112a3e13b4bba1c506 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Wed, 1 Apr 2020 18:53:53 +0200 Subject: [PATCH 0081/1003] Remove duplicate array of extras directory names --- Emby.Server.Implementations/Library/LibraryManager.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 8ec4d08be5..0ddef0bc24 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -2609,14 +2609,12 @@ namespace Emby.Server.Implementations.Library }).OrderBy(i => i.Path); } - private static readonly string[] ExtrasSubfolderNames = new[] { "extras", "specials", "shorts", "scenes", "featurettes", "behind the scenes", "deleted scenes", "interviews" }; - public IEnumerable