diff options
122 files changed, 6943 insertions, 9202 deletions
diff --git a/Emby.Dlna/PlayTo/PlayToController.cs b/Emby.Dlna/PlayTo/PlayToController.cs index 43e983054..9d7c0d365 100644 --- a/Emby.Dlna/PlayTo/PlayToController.cs +++ b/Emby.Dlna/PlayTo/PlayToController.cs @@ -908,7 +908,8 @@ namespace Emby.Dlna.PlayTo return 0; } - public Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken) + /// <inheritdoc /> + public Task SendMessage<T>(string name, Guid messageId, T data, CancellationToken cancellationToken) { if (_disposed) { @@ -924,10 +925,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.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index ffc916b98..74863b805 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -44,7 +44,6 @@ using Emby.Server.Implementations.Security; using Emby.Server.Implementations.Serialization; using Emby.Server.Implementations.Services; using Emby.Server.Implementations.Session; -using Emby.Server.Implementations.SocketSharp; using Emby.Server.Implementations.TV; using Emby.Server.Implementations.Updates; using MediaBrowser.Api; @@ -94,7 +93,6 @@ using MediaBrowser.Model.Serialization; using MediaBrowser.Model.Services; using MediaBrowser.Model.System; using MediaBrowser.Model.Tasks; -using MediaBrowser.Model.Updates; using MediaBrowser.Providers.Chapters; using MediaBrowser.Providers.Manager; using MediaBrowser.Providers.Plugins.TheTvdb; @@ -102,11 +100,10 @@ using MediaBrowser.Providers.Subtitles; using MediaBrowser.WebDashboard.Api; using MediaBrowser.XbmcMetadata.Providers; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Http.Extensions; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using OperatingSystem = MediaBrowser.Common.System.OperatingSystem; using Prometheus.DotNetRuntime; +using OperatingSystem = MediaBrowser.Common.System.OperatingSystem; namespace Emby.Server.Implementations { @@ -503,32 +500,8 @@ namespace Emby.Server.Implementations RegisterServices(serviceCollection); } - public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next) - { - if (!context.WebSockets.IsWebSocketRequest) - { - await next().ConfigureAwait(false); - return; - } - - await _httpServer.ProcessWebSocketRequest(context).ConfigureAwait(false); - } - - public async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> 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, LoggerFactory.CreateLogger<WebSocketSharpRequest>()); - await _httpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false); - } + public Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next) + => _httpServer.RequestHandler(context); /// <summary> /// Registers services/resources with the service collection that will be available via DI. @@ -546,13 +519,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton<IJsonSerializer, JsonSerializer>(); - // TODO: Remove support for injecting ILogger completely - serviceCollection.AddSingleton((provider) => - { - Logger.LogWarning("Injecting ILogger directly is deprecated and should be replaced with ILogger<T>"); - return Logger; - }); - serviceCollection.AddSingleton(_fileSystemManager); serviceCollection.AddSingleton<TvdbClientManager>(); @@ -621,7 +587,6 @@ namespace Emby.Server.Implementations serviceCollection.AddSingleton<ISearchEngine, SearchEngine>(); serviceCollection.AddSingleton<ServiceController>(); - serviceCollection.AddSingleton<IHttpListener, WebSocketSharpListener>(); serviceCollection.AddSingleton<IHttpServer, HttpListenerHost>(); serviceCollection.AddSingleton<IImageProcessor, ImageProcessor>(); @@ -1150,9 +1115,6 @@ namespace Emby.Server.Implementations ItemsByNamePath = ApplicationPaths.InternalMetadataPath, InternalMetadataPath = ApplicationPaths.InternalMetadataPath, CachePath = ApplicationPaths.CachePath, - HttpServerPortNumber = HttpPort, - SupportsHttps = SupportsHttps, - HttpsPortNumber = HttpsPort, OperatingSystem = OperatingSystem.Id.ToString(), OperatingSystemDisplayName = OperatingSystem.Name, CanSelfRestart = CanSelfRestart, @@ -1188,23 +1150,22 @@ namespace Emby.Server.Implementations }; } - public bool EnableHttps => SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps; - - public bool SupportsHttps => Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy; + /// <inheritdoc/> + public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.Configuration.EnableHttps; - public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp = false) + /// <inheritdoc/> + public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken) { try { // Return the first matched address, if found, or the first known local address var addresses = await GetLocalIpAddressesInternal(false, 1, cancellationToken).ConfigureAwait(false); - - foreach (var address in addresses) + if (addresses.Count == 0) { - return GetLocalApiUrl(address, forceHttp); + return null; } - return null; + return GetLocalApiUrl(addresses.First()); } catch (Exception ex) { @@ -1231,7 +1192,7 @@ namespace Emby.Server.Implementations } /// <inheritdoc /> - public string GetLocalApiUrl(IPAddress ipAddress, bool forceHttp = false) + public string GetLocalApiUrl(IPAddress ipAddress) { if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6) { @@ -1241,29 +1202,30 @@ namespace Emby.Server.Implementations str.CopyTo(span.Slice(1)); span[^1] = ']'; - return GetLocalApiUrl(span, forceHttp); + return GetLocalApiUrl(span); } - return GetLocalApiUrl(ipAddress.ToString(), forceHttp); + return GetLocalApiUrl(ipAddress.ToString()); } - /// <inheritdoc /> - public string GetLocalApiUrl(ReadOnlySpan<char> host, bool forceHttp = false) + /// <inheritdoc/> + public string GetLoopbackHttpApiUrl() { - var url = new StringBuilder(64); - bool useHttps = EnableHttps && !forceHttp; - url.Append(useHttps ? "https://" : "http://") - .Append(host) - .Append(':') - .Append(useHttps ? HttpsPort : HttpPort); - - string baseUrl = ServerConfigurationManager.Configuration.BaseUrl; - if (baseUrl.Length != 0) - { - url.Append(baseUrl); - } + return GetLocalApiUrl("127.0.0.1", Uri.UriSchemeHttp, HttpPort); + } - return url.ToString(); + /// <inheritdoc/> + public string GetLocalApiUrl(ReadOnlySpan<char> host, string scheme = null, int? port = null) + { + // NOTE: If no BaseUrl is set then UriBuilder appends a trailing slash, but if there is no BaseUrl it does + // not. For consistency, always trim the trailing slash. + return new UriBuilder + { + Scheme = scheme ?? (ListenWithHttps ? Uri.UriSchemeHttps : Uri.UriSchemeHttp), + Host = host.ToString(), + Port = port ?? (ListenWithHttps ? HttpsPort : HttpPort), + Path = ServerConfigurationManager.Configuration.BaseUrl + }.ToString().TrimEnd('/'); } public Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken) @@ -1297,7 +1259,7 @@ namespace Emby.Server.Implementations } } - var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); + var valid = await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); if (valid) { resultList.Add(address); @@ -1331,7 +1293,7 @@ namespace Emby.Server.Implementations private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase); - private async Task<bool> IsIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken) + private async Task<bool> IsLocalIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken) { if (address.Equals(IPAddress.Loopback) || address.Equals(IPAddress.IPv6Loopback)) @@ -1339,8 +1301,7 @@ namespace Emby.Server.Implementations return true; } - var apiUrl = GetLocalApiUrl(address); - apiUrl += "/system/ping"; + var apiUrl = GetLocalApiUrl(address) + "/system/ping"; if (_validAddressResults.TryGetValue(apiUrl, out var cachedResult)) { diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs index 96096e142..7f7c6a0be 100644 --- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs +++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs @@ -31,18 +31,18 @@ namespace Emby.Server.Implementations.Browser /// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored. /// </summary> /// <param name="appHost">The application host.</param> - /// <param name="url">The URL.</param> - private static void TryOpenUrl(IServerApplicationHost appHost, string url) + /// <param name="relativeUrl">The URL to open, relative to the server base URL.</param> + private static void TryOpenUrl(IServerApplicationHost appHost, string relativeUrl) { try { string baseUrl = appHost.GetLocalApiUrl("localhost"); - appHost.LaunchUrl(baseUrl + url); + appHost.LaunchUrl(baseUrl + relativeUrl); } catch (Exception ex) { var logger = appHost.Resolve<ILogger>(); - logger?.LogError(ex, "Failed to open browser window with URL {URL}", url); + logger?.LogError(ex, "Failed to open browser window with URL {URL}", relativeUrl); } } } diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 37d7fd479..878cee23c 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.EntryPoints .Append(config.PublicHttpsPort).Append(Separator) .Append(_appHost.HttpPort).Append(Separator) .Append(_appHost.HttpsPort).Append(Separator) - .Append(_appHost.EnableHttps).Append(Separator) + .Append(_appHost.ListenWithHttps).Append(Separator) .Append(config.EnableRemoteAccess).Append(Separator) .ToString(); } @@ -158,7 +158,7 @@ namespace Emby.Server.Implementations.EntryPoints { yield return CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort); - if (_appHost.EnableHttps) + if (_appHost.ListenWithHttps) { yield return CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort); } diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs index 211a0c1d9..794d55c04 100644 --- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs +++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs @@ -6,11 +6,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; @@ -22,15 +23,17 @@ using MediaBrowser.Model.Globalization; 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.Hosting; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Primitives; using ServiceStack.Text.Jsv; namespace Emby.Server.Implementations.HttpServer { - public class HttpListenerHost : IHttpServer, IDisposable + public class HttpListenerHost : IHttpServer { /// <summary> /// The key for a setting that specifies the default redirect path @@ -39,17 +42,17 @@ namespace Emby.Server.Implementations.HttpServer public const string DefaultRedirectKey = "HttpListenerHost:DefaultRedirectPath"; 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<Type, Func<string, object>> _funcParseFn; private readonly string _defaultRedirectPath; private readonly string _baseUrlPrefix; + private readonly Dictionary<Type, Type> _serviceOperationsMap = new Dictionary<Type, Type>(); - private readonly List<IWebSocketConnection> _webSocketConnections = new List<IWebSocketConnection>(); private readonly IHostEnvironment _hostEnvironment; private IWebSocketListener[] _webSocketListeners = Array.Empty<IWebSocketListener>(); @@ -63,10 +66,10 @@ namespace Emby.Server.Implementations.HttpServer INetworkManager networkManager, IJsonSerializer jsonSerializer, IXmlSerializer xmlSerializer, - IHttpListener socketListener, ILocalizationManager localizationManager, ServiceController serviceController, - IHostEnvironment hostEnvironment) + IHostEnvironment hostEnvironment, + ILoggerFactory loggerFactory) { _appHost = applicationHost; _logger = logger; @@ -76,11 +79,9 @@ namespace Emby.Server.Implementations.HttpServer _networkManager = networkManager; _jsonSerializer = jsonSerializer; _xmlSerializer = xmlSerializer; - _socketListener = socketListener; ServiceController = serviceController; - - _socketListener.WebSocketConnected = OnWebSocketConnected; _hostEnvironment = hostEnvironment; + _loggerFactory = loggerFactory; _funcParseFn = t => s => JsvReader.GetParseFn(t)(s); @@ -172,38 +173,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<IWebSocketConnection>(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) @@ -289,32 +258,6 @@ namespace Emby.Server.Implementations.HttpServer .Replace(_config.ApplicationPaths.ProgramDataPath, string.Empty, StringComparison.OrdinalIgnoreCase); } - /// <summary> - /// Shut down the Web Service - /// </summary> - public void Stop() - { - List<IWebSocketConnection> 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); @@ -424,33 +367,52 @@ namespace Emby.Server.Implementations.HttpServer return true; } + /// <summary> + /// Validate a connection from a remote IP address to a URL to see if a redirection to HTTPS is required. + /// </summary> + /// <returns>True if the request is valid, or false if the request is not valid and an HTTPS redirect is required.</returns> private bool ValidateSsl(string remoteIp, string urlString) { - if (_config.Configuration.RequireHttps && _appHost.EnableHttps && !_config.Configuration.IsBehindProxy) + if (_config.Configuration.RequireHttps + && _appHost.ListenWithHttps + && !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; } + /// <inheritdoc /> + 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); + } + /// <summary> /// Overridable method that can be used to implement a custom handler. /// </summary> - 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(); @@ -493,9 +455,10 @@ namespace Emby.Server.Implementations.HttpServer if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase)) { httpRes.StatusCode = 200; - httpRes.Headers.Add("Access-Control-Allow-Origin", "*"); - httpRes.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); - httpRes.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"); + foreach(var (key, value) in GetDefaultCorsHeaders(httpReq)) + { + httpRes.Headers.Add(key, value); + } httpRes.ContentType = "text/plain"; await httpRes.WriteAsync(string.Empty, cancellationToken).ConfigureAwait(false); return; @@ -578,6 +541,68 @@ namespace Emby.Server.Implementations.HttpServer } } + private async Task WebSocketRequestHandler(HttpContext context) + { + if (_disposed) + { + return; + } + + try + { + _logger.LogInformation("WS {IP} request", context.Connection.RemoteIpAddress); + + WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false); + + var connection = new WebSocketConnection( + _loggerFactory.CreateLogger<WebSocketConnection>(), + webSocket, + context.Connection.RemoteIpAddress, + context.Request.Query) + { + OnReceive = ProcessWebSocketMessageReceived + }; + + WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection)); + + await connection.ProcessAsync().ConfigureAwait(false); + _logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress); + } + catch (Exception ex) // Otherwise ASP.Net will ignore the exception + { + _logger.LogError(ex, "WS {IP} WebSocketRequestHandler error", context.Connection.RemoteIpAddress); + if (!context.Response.HasStarted) + { + context.Response.StatusCode = 500; + } + } + } + + /// <summary> + /// Get the default CORS headers + /// </summary> + /// <param name="req"></param> + /// <returns></returns> + public IDictionary<string, string> GetDefaultCorsHeaders(IRequest req) + { + var origin = req.Headers["Origin"]; + if (origin == StringValues.Empty) + { + origin = req.Headers["Host"]; + if (origin == StringValues.Empty) + { + origin = "*"; + } + } + + var headers = new Dictionary<string, string>(); + headers.Add("Access-Control-Allow-Origin", origin); + headers.Add("Access-Control-Allow-Credentials", "true"); + headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); + headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization, Cookie"); + return headers; + } + // Entry point for HttpListener public ServiceHandler GetServiceHandler(IHttpRequest httpReq) { @@ -624,7 +649,7 @@ namespace Emby.Server.Implementations.HttpServer ResponseFilters = new Action<IRequest, HttpResponse, object>[] { - new ResponseFilter(_logger).FilterResponse + new ResponseFilter(this, _logger).FilterResponse }; } @@ -685,11 +710,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"); @@ -708,28 +728,6 @@ namespace Emby.Server.Implementations.HttpServer return _baseUrlPrefix + NormalizeUrlPath(path); } - /// <inheritdoc /> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (_disposed) - { - return; - } - - if (disposing) - { - Stop(); - } - - _disposed = true; - } - /// <summary> /// Processes the web socket message received. /// </summary> @@ -741,8 +739,6 @@ namespace Emby.Server.Implementations.HttpServer return Task.CompletedTask; } - _logger.LogDebug("Websocket message received: {0}", result.MessageType); - IEnumerable<Task> GetTasks() { foreach (var x in _webSocketListeners) diff --git a/Emby.Server.Implementations/HttpServer/IHttpListener.cs b/Emby.Server.Implementations/HttpServer/IHttpListener.cs deleted file mode 100644 index 501593725..000000000 --- a/Emby.Server.Implementations/HttpServer/IHttpListener.cs +++ /dev/null @@ -1,39 +0,0 @@ -#pragma warning disable CS1591 - -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 - { - /// <summary> - /// Gets or sets the error handler. - /// </summary> - /// <value>The error handler.</value> - Func<Exception, IRequest, bool, bool, Task> ErrorHandler { get; set; } - - /// <summary> - /// Gets or sets the request handler. - /// </summary> - /// <value>The request handler.</value> - Func<IHttpRequest, string, string, string, CancellationToken, Task> RequestHandler { get; set; } - - /// <summary> - /// Gets or sets the web socket handler. - /// </summary> - /// <value>The web socket handler.</value> - Action<WebSocketConnectEventArgs> WebSocketConnected { get; set; } - - /// <summary> - /// Stops this instance. - /// </summary> - Task Stop(); - - Task ProcessWebSocketRequest(HttpContext ctx); - } -} diff --git a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs index 4089aa578..85c3db9b2 100644 --- a/Emby.Server.Implementations/HttpServer/ResponseFilter.cs +++ b/Emby.Server.Implementations/HttpServer/ResponseFilter.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.Text; +using MediaBrowser.Controller.Net; using MediaBrowser.Model.Services; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; @@ -13,14 +15,17 @@ namespace Emby.Server.Implementations.HttpServer /// </summary> public class ResponseFilter { + private readonly IHttpServer _server; private readonly ILogger _logger; /// <summary> /// Initializes a new instance of the <see cref="ResponseFilter"/> class. /// </summary> + /// <param name="server">The HTTP server.</param> /// <param name="logger">The logger.</param> - public ResponseFilter(ILogger logger) + public ResponseFilter(IHttpServer server, ILogger logger) { + _server = server; _logger = logger; } @@ -32,10 +37,16 @@ namespace Emby.Server.Implementations.HttpServer /// <param name="dto">The dto.</param> public void FilterResponse(IRequest req, HttpResponse res, object dto) { + foreach(var (key, value) in _server.GetDefaultCorsHeaders(req)) + { + res.Headers.Add(key, value); + } // Try to prevent compatibility view - res.Headers.Add("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization"); - res.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS"); - res.Headers.Add("Access-Control-Allow-Origin", "*"); + res.Headers["Access-Control-Allow-Headers"] = ("Accept, Accept-Language, Authorization, Cache-Control, " + + "Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, " + + "Content-Type, Cookie, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, " + + "Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, " + + "X-Emby-Authorization"); if (dto is Exception exception) { diff --git a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs index 2292d86a4..095725c50 100644 --- a/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs +++ b/Emby.Server.Implementations/HttpServer/WebSocketConnection.cs @@ -1,15 +1,18 @@ -using System; +#nullable enable + +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,69 +27,50 @@ namespace Emby.Server.Implementations.HttpServer private readonly ILogger _logger; /// <summary> - /// The json serializer. + /// The json serializer options. /// </summary> - private readonly IJsonSerializer _jsonSerializer; + private readonly JsonSerializerOptions _jsonOptions; /// <summary> /// The socket. /// </summary> - private readonly IWebSocket _socket; + private readonly WebSocket _socket; /// <summary> /// Initializes a new instance of the <see cref="WebSocketConnection" /> class. /// </summary> + /// <param name="logger">The logger.</param> /// <param name="socket">The socket.</param> /// <param name="remoteEndPoint">The remote end point.</param> - /// <param name="jsonSerializer">The json serializer.</param> - /// <param name="logger">The logger.</param> - /// <exception cref="ArgumentNullException">socket</exception> - public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger) + /// <param name="query">The query.</param> + public WebSocketConnection( + ILogger<WebSocketConnection> logger, + WebSocket socket, + IPAddress? remoteEndPoint, + IQueryCollection query) { - if (socket == null) - { - throw new ArgumentNullException(nameof(socket)); - } - - if (string.IsNullOrEmpty(remoteEndPoint)) - { - 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; + _logger = logger; _socket = socket; - _socket.OnReceiveBytes = OnReceiveInternal; - RemoteEndPoint = remoteEndPoint; - _logger = logger; + QueryString = query; - socket.Closed += OnSocketClosed; + _jsonOptions = JsonDefaults.GetOptions(); + LastActivityDate = DateTime.Now; } /// <inheritdoc /> - public event EventHandler<EventArgs> Closed; + public event EventHandler<EventArgs>? Closed; /// <summary> /// Gets or sets the remote end point. /// </summary> - public string RemoteEndPoint { get; private set; } + public IPAddress? RemoteEndPoint { get; } /// <summary> /// Gets or sets the receive action. /// </summary> /// <value>The receive action.</value> - public Func<WebSocketMessageInfo, Task> OnReceive { get; set; } + public Func<WebSocketMessageInfo, Task>? OnReceive { get; set; } /// <summary> /// Gets the last activity date. @@ -95,22 +79,10 @@ namespace Emby.Server.Implementations.HttpServer public DateTime LastActivityDate { get; private set; } /// <summary> - /// Gets the id. - /// </summary> - /// <value>The id.</value> - public Guid Id { get; private set; } - - /// <summary> - /// Gets or sets the URL. - /// </summary> - /// <value>The URL.</value> - public string Url { get; set; } - - /// <summary> /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - public IQueryCollection QueryString { get; set; } + public IQueryCollection QueryString { get; } /// <summary> /// Gets the state. @@ -118,138 +90,135 @@ namespace Emby.Server.Implementations.HttpServer /// <value>The state.</value> public WebSocketState State => _socket.State; - void OnSocketClosed(object sender, EventArgs e) + /// <summary> + /// Sends a message asynchronously. + /// </summary> + /// <typeparam name="T"></typeparam> + /// <param name="message">The message.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + public Task SendAsync<T>(WebSocketMessage<T> message, CancellationToken cancellationToken) { - Closed?.Invoke(this, EventArgs.Empty); + var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions); + return _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken); } - /// <summary> - /// Called when [receive]. - /// </summary> - /// <param name="bytes">The bytes.</param> - private void OnReceiveInternal(byte[] bytes) + /// <inheritdoc /> + public async Task ProcessAsync(CancellationToken cancellationToken = default) { - LastActivityDate = DateTime.UtcNow; + var pipe = new Pipe(); + var writer = pipe.Writer; - if (OnReceive == null) + ValueWebSocketReceiveResult receiveresult; + do { - return; - } - var charset = CharsetDetector.DetectFromBytes(bytes).Detected?.EncodingName; + // Allocate at least 512 bytes from the PipeWriter + Memory<byte> memory = writer.GetMemory(512); + try + { + receiveresult = await _socket.ReceiveAsync(memory, cancellationToken); + } + catch (WebSocketException ex) + { + _logger.LogWarning("WS {IP} error receiving data: {Message}", RemoteEndPoint, ex.Message); + break; + } - if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase)) - { - OnReceiveInternal(Encoding.UTF8.GetString(bytes, 0, bytes.Length)); - } - else + int bytesRead = receiveresult.Count; + if (bytesRead == 0) + { + break; + } + + // 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; + } + + LastActivityDate = DateTime.UtcNow; + + if (receiveresult.EndOfMessage) + { + await ProcessInternal(pipe.Reader).ConfigureAwait(false); + } + } while ( + (_socket.State == WebSocketState.Open || _socket.State == WebSocketState.Connecting) + && receiveresult.MessageType != WebSocketMessageType.Close); + + Closed?.Invoke(this, EventArgs.Empty); + + if (_socket.State == WebSocketState.Open + || _socket.State == WebSocketState.CloseReceived + || _socket.State == WebSocketState.CloseSent) { - OnReceiveInternal(Encoding.ASCII.GetString(bytes, 0, bytes.Length)); + await _socket.CloseAsync( + WebSocketCloseStatus.NormalClosure, + string.Empty, + cancellationToken).ConfigureAwait(false); } } - 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; - } + ReadResult result = await reader.ReadAsync().ConfigureAwait(false); + ReadOnlySequence<byte> buffer = result.Buffer; if (OnReceive == null) { + // Tell the PipeReader how much of the buffer we have consumed + reader.AdvanceTo(buffer.End); return; } + WebSocketMessage<object> stub; try { - var stub = (WebSocketMessage<object>)_jsonSerializer.DeserializeFromString(message, typeof(WebSocketMessage<object>)); - var info = new WebSocketMessageInfo + if (buffer.IsSingleSegment) { - MessageType = stub.MessageType, - Data = stub.Data?.ToString(), - Connection = this - }; - - OnReceive(info); + stub = JsonSerializer.Deserialize<WebSocketMessage<object>>(buffer.FirstSpan, _jsonOptions); + } + else + { + var buf = ArrayPool<byte>.Shared.Rent(Convert.ToInt32(buffer.Length)); + try + { + buffer.CopyTo(buf); + stub = JsonSerializer.Deserialize<WebSocketMessage<object>>(buf, _jsonOptions); + } + finally + { + ArrayPool<byte>.Shared.Return(buf); + } + } } - catch (Exception ex) + 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"); - } - } - - /// <summary> - /// Sends a message asynchronously. - /// </summary> - /// <typeparam name="T"></typeparam> - /// <param name="message">The message.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - /// <exception cref="ArgumentNullException">message</exception> - public Task SendAsync<T>(WebSocketMessage<T> message, CancellationToken cancellationToken) - { - if (message == null) - { - throw new ArgumentNullException(nameof(message)); - } - - var json = _jsonSerializer.SerializeToString(message); - - return SendAsync(json, cancellationToken); - } - - /// <summary> - /// Sends a message asynchronously. - /// </summary> - /// <param name="buffer">The buffer.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - public Task SendAsync(byte[] buffer, CancellationToken cancellationToken) - { - if (buffer == null) - { - throw new ArgumentNullException(nameof(buffer)); + return; } - cancellationToken.ThrowIfCancellationRequested(); + // Tell the PipeReader how much of the buffer we have consumed + reader.AdvanceTo(buffer.End); - return _socket.SendAsync(buffer, true, cancellationToken); - } + _logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub); - /// <inheritdoc /> - public Task SendAsync(string text, CancellationToken cancellationToken) - { - if (string.IsNullOrEmpty(text)) + var info = new WebSocketMessageInfo { - throw new ArgumentNullException(nameof(text)); - } + MessageType = stub.MessageType, + Data = stub.Data?.ToString(), // Data can be null + Connection = this + }; - cancellationToken.ThrowIfCancellationRequested(); - - return _socket.SendAsync(text, true, cancellationToken); - } - - /// <inheritdoc /> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// <summary> - /// Releases unmanaged and - optionally - managed resources. - /// </summary> - /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - _socket.Dispose(); - } + await OnReceive(info).ConfigureAwait(false); } } } diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index 85b1b6e32..6c9ba7c27 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio /// </summary> public class MusicAlbumResolver : ItemResolver<MusicAlbum> { - private readonly ILogger _logger; + private readonly ILogger<MusicAlbumResolver> _logger; private readonly IFileSystem _fileSystem; private readonly ILibraryManager _libraryManager; @@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio /// <param name="logger">The logger.</param> /// <param name="fileSystem">The file system.</param> /// <param name="libraryManager">The library manager.</param> - public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager) + public MusicAlbumResolver(ILogger<MusicAlbumResolver> logger, IFileSystem fileSystem, ILibraryManager libraryManager) { _logger = logger; _fileSystem = fileSystem; diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs index 681db4896..5f5cd0e92 100644 --- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs +++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs @@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio /// </summary> public class MusicArtistResolver : ItemResolver<MusicArtist> { - private readonly ILogger _logger; + private readonly ILogger<MusicAlbumResolver> _logger; private readonly IFileSystem _fileSystem; private readonly ILibraryManager _libraryManager; private readonly IServerConfigurationManager _config; @@ -23,12 +23,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio /// <summary> /// Initializes a new instance of the <see cref="MusicArtistResolver"/> class. /// </summary> - /// <param name="logger">The logger.</param> + /// <param name="logger">The logger for the created <see cref="MusicAlbumResolver"/> instances.</param> /// <param name="fileSystem">The file system.</param> /// <param name="libraryManager">The library manager.</param> /// <param name="config">The configuration manager.</param> public MusicArtistResolver( - ILogger<MusicArtistResolver> logger, + ILogger<MusicAlbumResolver> logger, IFileSystem fileSystem, ILibraryManager libraryManager, IServerConfigurationManager config) diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index 33f4ca146..3efe1ee25 100644 --- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -1059,7 +1059,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV { var stream = new MediaSourceInfo { - EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveRecordings/" + info.Id + "/stream", + EncoderPath = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveRecordings/" + info.Id + "/stream", EncoderProtocol = MediaProtocol.Http, Path = info.Path, Protocol = MediaProtocol.File, diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs index d89a816b3..82b1f3cf1 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs @@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun //OpenedMediaSource.Path = tempFile; //OpenedMediaSource.ReadAtNativeFramerate = true; - MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; + MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; MediaSource.Protocol = MediaProtocol.Http; //OpenedMediaSource.SupportsDirectPlay = false; //OpenedMediaSource.SupportsDirectStream = true; diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs index f5dda79db..f7c9c736e 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs @@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts public M3UTunerHost( IServerConfigurationManager config, IMediaSourceManager mediaSourceManager, - ILogger logger, + ILogger<M3UTunerHost> logger, IJsonSerializer jsonSerializer, IFileSystem fileSystem, IHttpClient httpClient, @@ -83,7 +83,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts return Task.FromResult(list); } - private static readonly string[] _disallowedSharedStreamExtensions = new string[] + private static readonly string[] _disallowedSharedStreamExtensions = { ".mkv", ".mp4", diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs index 0e600202a..083fcd029 100644 --- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs +++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs @@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts //OpenedMediaSource.Path = tempFile; //OpenedMediaSource.ReadAtNativeFramerate = true; - MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; + MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts"; MediaSource.Protocol = MediaProtocol.Http; //OpenedMediaSource.Path = TempFilePath; diff --git a/Emby.Server.Implementations/Localization/Core/bn.json b/Emby.Server.Implementations/Localization/Core/bn.json index ef7792356..4949b10e6 100644 --- a/Emby.Server.Implementations/Localization/Core/bn.json +++ b/Emby.Server.Implementations/Localization/Core/bn.json @@ -91,5 +91,7 @@ "HeaderNextUp": "এরপরে আসছে", "HeaderLiveTV": "লাইভ টিভি", "HeaderFavoriteSongs": "প্রিয় গানগুলো", - "HeaderFavoriteShows": "প্রিয় শোগুলো" + "HeaderFavoriteShows": "প্রিয় শোগুলো", + "TasksLibraryCategory": "গ্রন্থাগার", + "TasksMaintenanceCategory": "রক্ষণাবেক্ষণ" } diff --git a/Emby.Server.Implementations/Localization/Core/gsw.json b/Emby.Server.Implementations/Localization/Core/gsw.json index c8291a202..8780a884b 100644 --- a/Emby.Server.Implementations/Localization/Core/gsw.json +++ b/Emby.Server.Implementations/Localization/Core/gsw.json @@ -103,5 +103,16 @@ "TasksChannelsCategory": "Internet Kanäle", "TasksApplicationCategory": "Applikation", "TasksLibraryCategory": "Bibliothek", - "TasksMaintenanceCategory": "Verwaltung" + "TasksMaintenanceCategory": "Verwaltung", + "TaskDownloadMissingSubtitlesDescription": "Durchsucht das Internet nach fehlenden Untertiteln, basierend auf den Metadaten Einstellungen.", + "TaskDownloadMissingSubtitles": "Lade fehlende Untertitel herunter", + "TaskRefreshChannelsDescription": "Aktualisiert Internet Kanal Informationen.", + "TaskRefreshChannels": "Aktualisiere Kanäle", + "TaskCleanTranscodeDescription": "Löscht Transkodierdateien welche älter als ein Tag sind.", + "TaskCleanTranscode": "Räume Transcodier Verzeichnis auf", + "TaskUpdatePluginsDescription": "Lädt Aktualisierungen für Erweiterungen herunter und installiert diese, für welche automatische Aktualisierungen konfiguriert sind.", + "TaskUpdatePlugins": "Aktualisiere Erweiterungen", + "TaskRefreshPeopleDescription": "Aktualisiert Metadaten für Schausteller und Regisseure in deiner Bibliothek.", + "TaskRefreshPeople": "Aktualisiere Schauspieler", + "TaskCleanLogsDescription": "Löscht Log Dateien die älter als {0} Tage sind." } diff --git a/Emby.Server.Implementations/Localization/Core/he.json b/Emby.Server.Implementations/Localization/Core/he.json index 8abe31d2a..4e54b9f7a 100644 --- a/Emby.Server.Implementations/Localization/Core/he.json +++ b/Emby.Server.Implementations/Localization/Core/he.json @@ -99,5 +99,13 @@ "TaskCleanCache": "נקה תיקיית מטמון", "TasksApplicationCategory": "יישום", "TasksLibraryCategory": "ספרייה", - "TasksMaintenanceCategory": "תחזוקה" + "TasksMaintenanceCategory": "תחזוקה", + "TaskUpdatePlugins": "עדכן תוספים", + "TaskRefreshPeopleDescription": "מעדכן מטא נתונים עבור שחקנים ובמאים בספריית המדיה שלך.", + "TaskRefreshPeople": "רענן אנשים", + "TaskCleanLogsDescription": "מוחק קבצי יומן בני יותר מ- {0} ימים.", + "TaskCleanLogs": "נקה תיקיית יומן", + "TaskRefreshLibraryDescription": "סורק את ספריית המדיה שלך אחר קבצים חדשים ומרענן מטא נתונים.", + "TaskRefreshChapterImagesDescription": "יוצר תמונות ממוזערות לסרטונים שיש להם פרקים.", + "TasksChannelsCategory": "ערוצי אינטרנט" } diff --git a/Emby.Server.Implementations/Localization/Core/it.json b/Emby.Server.Implementations/Localization/Core/it.json index 0758bbe9c..7f5a56e86 100644 --- a/Emby.Server.Implementations/Localization/Core/it.json +++ b/Emby.Server.Implementations/Localization/Core/it.json @@ -5,7 +5,7 @@ "Artists": "Artisti", "AuthenticationSucceededWithUserName": "{0} autenticato con successo", "Books": "Libri", - "CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera dal device {0}", + "CameraImageUploadedFrom": "È stata caricata una nuova fotografia da {0}", "Channels": "Canali", "ChapterNameValue": "Capitolo {0}", "Collections": "Collezioni", diff --git a/Emby.Server.Implementations/Localization/Core/nb.json b/Emby.Server.Implementations/Localization/Core/nb.json index 50d0d083c..5637ce346 100644 --- a/Emby.Server.Implementations/Localization/Core/nb.json +++ b/Emby.Server.Implementations/Localization/Core/nb.json @@ -97,5 +97,9 @@ "TasksApplicationCategory": "Applikasjon", "TasksLibraryCategory": "Bibliotek", "TasksMaintenanceCategory": "Vedlikehold", - "TaskCleanCache": "Tøm buffer katalog" + "TaskCleanCache": "Tøm buffer katalog", + "TaskRefreshLibrary": "Skann mediebibliotek", + "TaskRefreshChapterImagesDescription": "Lager forhåndsvisningsbilder for videoer som har kapitler.", + "TaskRefreshChapterImages": "Trekk ut Kapittelbilder", + "TaskCleanCacheDescription": "Sletter mellomlagrede filer som ikke lengre trengs av systemet." } diff --git a/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs b/Emby.Server.Implementations/Middleware/WebSocketMiddleware.cs deleted file mode 100644 index fda32da5e..000000000 --- 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<WebSocketMiddleware> _logger; - private readonly WebSocketManager _webSocketManager; - - public WebSocketMiddleware(RequestDelegate next, ILogger<WebSocketMiddleware> 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/Net/IWebSocket.cs b/Emby.Server.Implementations/Net/IWebSocket.cs deleted file mode 100644 index 4d160aa66..000000000 --- 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 -{ - /// <summary> - /// Interface IWebSocket - /// </summary> - public interface IWebSocket : IDisposable - { - /// <summary> - /// Occurs when [closed]. - /// </summary> - event EventHandler<EventArgs> Closed; - - /// <summary> - /// Gets or sets the state. - /// </summary> - /// <value>The state.</value> - WebSocketState State { get; } - - /// <summary> - /// Gets or sets the receive action. - /// </summary> - /// <value>The receive action.</value> - Action<byte[]> OnReceiveBytes { get; set; } - - /// <summary> - /// Sends the async. - /// </summary> - /// <param name="bytes">The bytes.</param> - /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken); - - /// <summary> - /// Sends the asynchronous. - /// </summary> - /// <param name="text">The text.</param> - /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - 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 6880766f9..000000000 --- a/Emby.Server.Implementations/Net/WebSocketConnectEventArgs.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using Microsoft.AspNetCore.Http; - -namespace Emby.Server.Implementations.Net -{ - public class WebSocketConnectEventArgs : EventArgs - { - /// <summary> - /// Gets or sets the URL. - /// </summary> - /// <value>The URL.</value> - public string Url { get; set; } - /// <summary> - /// Gets or sets the query string. - /// </summary> - /// <value>The query string.</value> - public IQueryCollection QueryString { get; set; } - /// <summary> - /// Gets or sets the web socket. - /// </summary> - /// <value>The web socket.</value> - public IWebSocket WebSocket { get; set; } - /// <summary> - /// Gets or sets the endpoint. - /// </summary> - /// <value>The endpoint.</value> - 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 dfb81816c..000000000 --- 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<string, string>(), cancellationToken); - } - - private Task SendMessage(string name, string messageId, Dictionary<string, string> 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<string, string>(); - - 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<string, string>(); - - 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<string>(); - public Task SendMessage<T>(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<string, string> 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 c93c02c48..df98a35bc 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -477,8 +477,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; @@ -1042,12 +1041,12 @@ namespace Emby.Server.Implementations.Session private static async Task SendMessageToSession<T>(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); } } @@ -1055,13 +1054,13 @@ namespace Emby.Server.Implementations.Session { IEnumerable<Task> 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); } } } @@ -1762,7 +1761,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 930f2d35d..d4e4ba1f2 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 /// <summary> /// Class SessionWebSocketListener /// </summary> - public class SessionWebSocketListener : IWebSocketListener, IDisposable + public sealed class SessionWebSocketListener : IWebSocketListener, IDisposable { /// <summary> /// The _session manager @@ -23,42 +22,41 @@ namespace Emby.Server.Implementations.Session /// The _logger /// </summary> private readonly ILogger _logger; - - /// <summary> - /// The _dto service - /// </summary> - private readonly IJsonSerializer _json; + private readonly ILoggerFactory _loggerFactory; private readonly IHttpServer _httpServer; - /// <summary> /// Initializes a new instance of the <see cref="SessionWebSocketListener" /> class. /// </summary> + /// <param name="logger">The logger.</param> /// <param name="sessionManager">The session manager.</param> /// <param name="loggerFactory">The logger factory.</param> - /// <param name="json">The json.</param> /// <param name="httpServer">The HTTP server.</param> - public SessionWebSocketListener(ISessionManager sessionManager, ILoggerFactory loggerFactory, IJsonSerializer json, IHttpServer httpServer) + public SessionWebSocketListener( + ILogger<SessionWebSocketListener> 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<IWebSocketConnection> e) + private void OnServerManagerWebSocketConnected(object sender, GenericEventArgs<IWebSocketConnection> 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); } 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); } } @@ -79,9 +77,10 @@ namespace Emby.Server.Implementations.Session return _sessionManager.GetSessionByAuthenticationToken(token, deviceId, remoteEndpoint); } + /// <inheritdoc /> public void Dispose() { - _httpServer.WebSocketConnected -= _serverManager_WebSocketConnected; + _httpServer.WebSocketConnected -= OnServerManagerWebSocketConnected; } /// <summary> @@ -94,7 +93,8 @@ namespace Emby.Server.Implementations.Session private void EnsureController(SessionInfo session, IWebSocketConnection connection) { - var controllerInfo = session.EnsureController<WebSocketController>(s => new WebSocketController(s, _logger, _sessionManager)); + var controllerInfo = session.EnsureController<WebSocketController>( + s => new WebSocketController(_loggerFactory.CreateLogger<WebSocketController>(), 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 0d483c55f..a0274acd2 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; @@ -11,60 +15,63 @@ 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<IWebSocketConnection> 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 readonly List<IWebSocketConnection> _sockets; + private bool _disposed = false; + + public WebSocketController( + ILogger<WebSocketController> logger, + SessionInfo session, + ISessionManager sessionManager) { - Session = session; _logger = logger; + _session = session; _sessionManager = sessionManager; - Sockets = new List<IWebSocketConnection>(); + _sockets = new List<IWebSocketConnection>(); } private bool HasOpenSockets => GetActiveSockets().Any(); + /// <inheritdoc /> public bool SupportsMediaControl => HasOpenSockets; + /// <inheritdoc /> public bool IsSessionActive => HasOpenSockets; private IEnumerable<IWebSocketConnection> 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) { var connection = (IWebSocketConnection)sender; - var sockets = Sockets.ToList(); - sockets.Remove(connection); - - Sockets = sockets; - - _sessionManager.CloseIfNeeded(Session); + _logger.LogDebug("Removing websocket from session {Session}", _session.Id); + _sockets.Remove(connection); + connection.Closed -= OnConnectionClosed; + _sessionManager.CloseIfNeeded(_session); } - public Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken) + /// <inheritdoc /> + public Task SendMessage<T>( + string name, + Guid messageId, + T data, + CancellationToken cancellationToken) { var socket = GetActiveSockets() + .OrderByDescending(i => i.LastActivityDate) .FirstOrDefault(); if (socket == null) @@ -72,21 +79,30 @@ namespace Emby.Server.Implementations.Session return Task.CompletedTask; } - return socket.SendAsync(new WebSocketMessage<T> - { - Data = data, - MessageType = name, - MessageId = messageId - - }, cancellationToken); + return socket.SendAsync( + new WebSocketMessage<T> + { + Data = data, + MessageType = name, + MessageId = messageId + }, + cancellationToken); } + /// <inheritdoc /> public void Dispose() { - foreach (var socket in Sockets.ToList()) + if (_disposed) { - socket.Closed -= connection_Closed; + return; } + + foreach (var socket in _sockets) + { + socket.Closed -= OnConnectionClosed; + } + + _disposed = true; } } } diff --git a/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs b/Emby.Server.Implementations/SocketSharp/SharpWebSocket.cs deleted file mode 100644 index 67521d6c6..000000000 --- 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 - { - /// <summary> - /// The logger - /// </summary> - private readonly ILogger _logger; - - public event EventHandler<EventArgs> Closed; - - /// <summary> - /// Gets or sets the web socket. - /// </summary> - /// <value>The web socket.</value> - 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)); - } - - /// <summary> - /// Gets the state. - /// </summary> - /// <value>The state.</value> - public WebSocketState State => _webSocket.State; - - /// <summary> - /// Sends the async. - /// </summary> - /// <param name="bytes">The bytes.</param> - /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - public Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken) - { - return _webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Binary, endOfMessage, cancellationToken); - } - - /// <summary> - /// Sends the asynchronous. - /// </summary> - /// <param name="text">The text.</param> - /// <param name="endOfMessage">if set to <c>true</c> [end of message].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - public Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken) - { - return _webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(text)), WebSocketMessageType.Text, endOfMessage, cancellationToken); - } - - /// <summary> - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// </summary> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// <summary> - /// Releases unmanaged and - optionally - managed resources. - /// </summary> - /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - 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; - } - - /// <summary> - /// Gets or sets the receive action. - /// </summary> - /// <value>The receive action.</value> - public Action<byte[]> OnReceiveBytes { get; set; } - } -} diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs deleted file mode 100644 index b85750c9b..000000000 --- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpListener.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.WebSockets; -using System.Threading; -using System.Threading.Tasks; -using Emby.Server.Implementations.HttpServer; -using Emby.Server.Implementations.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<WebSocketSharpListener> logger) - { - _logger = logger; - _disposeCancellationToken = _disposeCancellationTokenSource.Token; - } - - public Func<Exception, IRequest, bool, bool, Task> ErrorHandler { get; set; } - - public Func<IHttpRequest, string, string, string, CancellationToken, Task> RequestHandler { get; set; } - - public Action<WebSocketConnectEventArgs> 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<byte>(); - - 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; - } - - /// <summary> - /// Releases the unmanaged resources and disposes of the managed resources used. - /// </summary> - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private bool _disposed; - - /// <summary> - /// Releases the unmanaged resources and disposes of the managed resources used. - /// </summary> - /// <param name="disposing">Whether or not the managed resources should be disposed.</param> - protected virtual void Dispose(bool disposing) - { - if (_disposed) - { - return; - } - - if (disposing) - { - Stop().GetAwaiter().GetResult(); - } - - _disposed = true; - } - } -} diff --git a/Emby.Server.Implementations/WebSockets/WebSocketHandler.cs b/Emby.Server.Implementations/WebSockets/WebSocketHandler.cs deleted file mode 100644 index eb1877440..000000000 --- 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<object> message, TaskCompletionSource<bool> taskCompletionSource); - } -} diff --git a/Emby.Server.Implementations/WebSockets/WebSocketManager.cs b/Emby.Server.Implementations/WebSockets/WebSocketManager.cs deleted file mode 100644 index 31a7468fb..000000000 --- a/Emby.Server.Implementations/WebSockets/WebSocketManager.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.WebSockets; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -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<WebSocketManager> _logger; - private const int BufferSize = 4096; - - public WebSocketManager(IWebSocketHandler[] webSocketHandlers, IJsonSerializer jsonSerializer, ILogger<WebSocketManager> logger) - { - _webSocketHandlers = webSocketHandlers; - _jsonSerializer = jsonSerializer; - _logger = logger; - } - - public async Task OnWebSocketConnected(WebSocket webSocket) - { - var taskCompletionSource = new TaskCompletionSource<bool>(); - var cancellationToken = new CancellationTokenSource().Token; - WebSocketReceiveResult result; - var message = new List<byte>(); - - // 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<bool> 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<WebSocketMessage<object>>(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/Jellyfin.Data/DbContexts/Jellyfin.cs b/Jellyfin.Data/DbContexts/Jellyfin.cs deleted file mode 100644 index fd488ce7d..000000000 --- a/Jellyfin.Data/DbContexts/Jellyfin.cs +++ /dev/null @@ -1,1140 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; -using System.Collections.Generic; -using System.Linq; -using System.ComponentModel.DataAnnotations.Schema; -using Microsoft.EntityFrameworkCore; - -namespace Jellyfin.Data.DbContexts -{ - /// <inheritdoc/> - public partial class Jellyfin : DbContext - { - #region DbSets - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Artwork> Artwork { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Book> Books { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.BookMetadata> BookMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Chapter> Chapters { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Collection> Collections { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CollectionItem> CollectionItems { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Company> Companies { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CompanyMetadata> CompanyMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CustomItem> CustomItems { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.CustomItemMetadata> CustomItemMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Episode> Episodes { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.EpisodeMetadata> EpisodeMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Genre> Genres { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Group> Groups { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Library> Libraries { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.LibraryItem> LibraryItems { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.LibraryRoot> LibraryRoot { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MediaFile> MediaFiles { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MediaFileStream> MediaFileStream { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Metadata> Metadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MetadataProvider> MetadataProviders { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MetadataProviderId> MetadataProviderIds { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Movie> Movies { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MovieMetadata> MovieMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MusicAlbum> MusicAlbums { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata> MusicAlbumMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Permission> Permissions { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Person> People { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.PersonRole> PersonRoles { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Photo> Photo { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.PhotoMetadata> PhotoMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Preference> Preferences { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Rating> Ratings { get; set; } - - /// <summary> - /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to - /// store review ratings, not age ratings - /// </summary> - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.RatingSource> RatingSources { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Release> Releases { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Season> Seasons { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.SeasonMetadata> SeasonMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Series> Series { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.SeriesMetadata> SeriesMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.Track> Tracks { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.TrackMetadata> TrackMetadata { get; set; } - public virtual Microsoft.EntityFrameworkCore.DbSet<global::Jellyfin.Data.Entities.User> Users { get; set; } - #endregion DbSets - - /// <summary> - /// Default connection string - /// </summary> - public static string ConnectionString { get; set; } = @"Data Source=jellyfin.db"; - - /// <inheritdoc /> - public Jellyfin(DbContextOptions<Jellyfin> options) : base(options) - { - } - - partial void CustomInit(DbContextOptionsBuilder optionsBuilder); - - /// <inheritdoc /> - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - CustomInit(optionsBuilder); - } - - partial void OnModelCreatingImpl(ModelBuilder modelBuilder); - partial void OnModelCreatedImpl(ModelBuilder modelBuilder); - - /// <inheritdoc /> - protected override void OnModelCreating(ModelBuilder modelBuilder) - { - base.OnModelCreating(modelBuilder); - OnModelCreatingImpl(modelBuilder); - - modelBuilder.HasDefaultSchema("jellyfin"); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>() - .ToTable("Artwork") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>() - .Property(t => t.Path) - .HasMaxLength(65535) - .IsRequired() - .HasField("_Path") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>() - .Property(t => t.Kind) - .IsRequired() - .HasField("_Kind") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>().HasIndex(t => t.Kind); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Artwork>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Book>() - .HasMany(x => x.BookMetadata) - .WithOne() - .HasForeignKey("BookMetadata_BookMetadata_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Book>() - .HasMany(x => x.Releases) - .WithOne() - .HasForeignKey("Release_Releases_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.BookMetadata>() - .Property(t => t.ISBN) - .HasField("_ISBN") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.BookMetadata>() - .HasMany(x => x.Publishers) - .WithOne() - .HasForeignKey("Company_Publishers_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>() - .ToTable("Chapter") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>() - .Property(t => t.Name) - .HasMaxLength(1024) - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>() - .Property(t => t.Language) - .HasMaxLength(3) - .IsRequired() - .HasField("_Language") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>() - .Property(t => t.TimeStart) - .IsRequired() - .HasField("_TimeStart") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>() - .Property(t => t.TimeEnd) - .HasField("_TimeEnd") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Chapter>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>() - .ToTable("Collection") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>() - .Property(t => t.Name) - .HasMaxLength(1024) - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Collection>() - .HasMany(x => x.CollectionItem) - .WithOne() - .HasForeignKey("CollectionItem_CollectionItem_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>() - .ToTable("CollectionItem") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>() - .HasOne(x => x.LibraryItem) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.CollectionItem>("LibraryItem_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>() - .HasOne(x => x.Next) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.CollectionItem>("CollectionItem_Next_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CollectionItem>() - .HasOne(x => x.Previous) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.CollectionItem>("CollectionItem_Previous_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>() - .ToTable("Company") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>() - .HasMany(x => x.CompanyMetadata) - .WithOne() - .HasForeignKey("CompanyMetadata_CompanyMetadata_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Company>() - .HasOne(x => x.Parent) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.Company>("Company_Parent_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>() - .Property(t => t.Description) - .HasMaxLength(65535) - .HasField("_Description") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>() - .Property(t => t.Headquarters) - .HasMaxLength(255) - .HasField("_Headquarters") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>() - .Property(t => t.Country) - .HasMaxLength(2) - .HasField("_Country") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CompanyMetadata>() - .Property(t => t.Homepage) - .HasMaxLength(1024) - .HasField("_Homepage") - .UsePropertyAccessMode(PropertyAccessMode.Property); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.CustomItem>() - .HasMany(x => x.CustomItemMetadata) - .WithOne() - .HasForeignKey("CustomItemMetadata_CustomItemMetadata_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.CustomItem>() - .HasMany(x => x.Releases) - .WithOne() - .HasForeignKey("Release_Releases_Id") - .IsRequired(); - - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Episode>() - .Property(t => t.EpisodeNumber) - .HasField("_EpisodeNumber") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Episode>() - .HasMany(x => x.Releases) - .WithOne() - .HasForeignKey("Release_Releases_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Episode>() - .HasMany(x => x.EpisodeMetadata) - .WithOne() - .HasForeignKey("EpisodeMetadata_EpisodeMetadata_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.EpisodeMetadata>() - .Property(t => t.Outline) - .HasMaxLength(1024) - .HasField("_Outline") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.EpisodeMetadata>() - .Property(t => t.Plot) - .HasMaxLength(65535) - .HasField("_Plot") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.EpisodeMetadata>() - .Property(t => t.Tagline) - .HasMaxLength(1024) - .HasField("_Tagline") - .UsePropertyAccessMode(PropertyAccessMode.Property); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>() - .ToTable("Genre") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>() - .Property(t => t.Name) - .HasMaxLength(255) - .IsRequired() - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>().HasIndex(t => t.Name) - .IsUnique(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Genre>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>() - .ToTable("Groups") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>() - .Property(t => t.Id) - .IsRequired() - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>() - .Property(t => t.Name) - .HasMaxLength(255) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>().Property<byte[]>("Timestamp").IsConcurrencyToken(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>() - .HasMany(x => x.GroupPermissions) - .WithOne() - .HasForeignKey("Permission_GroupPermissions_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>() - .HasMany(x => x.ProviderMappings) - .WithOne() - .HasForeignKey("ProviderMapping_ProviderMappings_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Group>() - .HasMany(x => x.Preferences) - .WithOne() - .HasForeignKey("Preference_Preferences_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>() - .ToTable("Library") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>() - .Property(t => t.Name) - .HasMaxLength(1024) - .IsRequired() - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Library>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>() - .ToTable("LibraryItem") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>() - .Property(t => t.UrlId) - .IsRequired() - .HasField("_UrlId") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>().HasIndex(t => t.UrlId) - .IsUnique(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>() - .Property(t => t.DateAdded) - .IsRequired() - .HasField("_DateAdded") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryItem>() - .HasOne(x => x.LibraryRoot) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.LibraryItem>("LibraryRoot_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>() - .ToTable("LibraryRoot") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>() - .Property(t => t.Path) - .HasMaxLength(65535) - .IsRequired() - .HasField("_Path") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>() - .Property(t => t.NetworkPath) - .HasMaxLength(65535) - .HasField("_NetworkPath") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.LibraryRoot>() - .HasOne(x => x.Library) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.LibraryRoot>("Library_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>() - .ToTable("MediaFile") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>() - .Property(t => t.Path) - .HasMaxLength(65535) - .IsRequired() - .HasField("_Path") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>() - .Property(t => t.Kind) - .IsRequired() - .HasField("_Kind") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFile>() - .HasMany(x => x.MediaFileStreams) - .WithOne() - .HasForeignKey("MediaFileStream_MediaFileStreams_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>() - .ToTable("MediaFileStream") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>() - .Property(t => t.StreamNumber) - .IsRequired() - .HasField("_StreamNumber") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MediaFileStream>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .ToTable("Metadata") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.Title) - .HasMaxLength(1024) - .IsRequired() - .HasField("_Title") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.OriginalTitle) - .HasMaxLength(1024) - .HasField("_OriginalTitle") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.SortTitle) - .HasMaxLength(1024) - .HasField("_SortTitle") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.Language) - .HasMaxLength(3) - .IsRequired() - .HasField("_Language") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.ReleaseDate) - .HasField("_ReleaseDate") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.DateAdded) - .IsRequired() - .HasField("_DateAdded") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.DateModified) - .IsRequired() - .HasField("_DateModified") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .HasMany(x => x.PersonRoles) - .WithOne() - .HasForeignKey("PersonRole_PersonRoles_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .HasMany(x => x.Genres) - .WithOne() - .HasForeignKey("Genre_Genres_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .HasMany(x => x.Artwork) - .WithOne() - .HasForeignKey("Artwork_Artwork_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .HasMany(x => x.Ratings) - .WithOne() - .HasForeignKey("Rating_Ratings_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Metadata>() - .HasMany(x => x.Sources) - .WithOne() - .HasForeignKey("MetadataProviderId_Sources_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>() - .ToTable("MetadataProvider") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>() - .Property(t => t.Name) - .HasMaxLength(1024) - .IsRequired() - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProvider>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>() - .ToTable("MetadataProviderId") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>() - .Property(t => t.ProviderId) - .HasMaxLength(255) - .IsRequired() - .HasField("_ProviderId") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MetadataProviderId>() - .HasOne(x => x.MetadataProvider) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.MetadataProviderId>("MetadataProvider_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Movie>() - .HasMany(x => x.Releases) - .WithOne() - .HasForeignKey("Release_Releases_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Movie>() - .HasMany(x => x.MovieMetadata) - .WithOne() - .HasForeignKey("MovieMetadata_MovieMetadata_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>() - .Property(t => t.Outline) - .HasMaxLength(1024) - .HasField("_Outline") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>() - .Property(t => t.Plot) - .HasMaxLength(65535) - .HasField("_Plot") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>() - .Property(t => t.Tagline) - .HasMaxLength(1024) - .HasField("_Tagline") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>() - .Property(t => t.Country) - .HasMaxLength(2) - .HasField("_Country") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MovieMetadata>() - .HasMany(x => x.Studios) - .WithOne() - .HasForeignKey("Company_Studios_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbum>() - .HasMany(x => x.MusicAlbumMetadata) - .WithOne() - .HasForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbum>() - .HasMany(x => x.Tracks) - .WithOne() - .HasForeignKey("Track_Tracks_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>() - .Property(t => t.Barcode) - .HasMaxLength(255) - .HasField("_Barcode") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>() - .Property(t => t.LabelNumber) - .HasMaxLength(255) - .HasField("_LabelNumber") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>() - .Property(t => t.Country) - .HasMaxLength(2) - .HasField("_Country") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.MusicAlbumMetadata>() - .HasMany(x => x.Labels) - .WithOne() - .HasForeignKey("Company_Labels_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>() - .ToTable("Permissions") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>() - .Property(t => t.Id) - .IsRequired() - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>() - .Property(t => t.Kind) - .IsRequired() - .HasField("_Kind") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>() - .Property(t => t.Value) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Permission>().Property<byte[]>("Timestamp").IsConcurrencyToken(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .ToTable("Person") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .Property(t => t.UrlId) - .IsRequired() - .HasField("_UrlId") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .Property(t => t.Name) - .HasMaxLength(1024) - .IsRequired() - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .Property(t => t.SourceId) - .HasMaxLength(255) - .HasField("_SourceId") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .Property(t => t.DateAdded) - .IsRequired() - .HasField("_DateAdded") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .Property(t => t.DateModified) - .IsRequired() - .HasField("_DateModified") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Person>() - .HasMany(x => x.Sources) - .WithOne() - .HasForeignKey("MetadataProviderId_Sources_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .ToTable("PersonRole") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .Property(t => t.Role) - .HasMaxLength(1024) - .HasField("_Role") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .Property(t => t.Type) - .IsRequired() - .HasField("_Type") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .HasOne(x => x.Person) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.PersonRole>("Person_Id") - .IsRequired() - .OnDelete(DeleteBehavior.Cascade); - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .HasOne(x => x.Artwork) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.PersonRole>("Artwork_Artwork_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.PersonRole>() - .HasMany(x => x.Sources) - .WithOne() - .HasForeignKey("MetadataProviderId_Sources_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Photo>() - .HasMany(x => x.PhotoMetadata) - .WithOne() - .HasForeignKey("PhotoMetadata_PhotoMetadata_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Photo>() - .HasMany(x => x.Releases) - .WithOne() - .HasForeignKey("Release_Releases_Id") - .IsRequired(); - - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>() - .ToTable("Preferences") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>() - .Property(t => t.Id) - .IsRequired() - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>() - .Property(t => t.Kind) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>() - .Property(t => t.Value) - .HasMaxLength(65535) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Preference>().Property<byte[]>("Timestamp").IsConcurrencyToken(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>() - .ToTable("ProviderMappings") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>() - .Property(t => t.Id) - .IsRequired() - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>() - .Property(t => t.ProviderName) - .HasMaxLength(255) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>() - .Property(t => t.ProviderSecrets) - .HasMaxLength(65535) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>() - .Property(t => t.ProviderData) - .HasMaxLength(65535) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.ProviderMapping>().Property<byte[]>("Timestamp").IsConcurrencyToken(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>() - .ToTable("Rating") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>() - .Property(t => t.Value) - .IsRequired() - .HasField("_Value") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>() - .Property(t => t.Votes) - .HasField("_Votes") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Rating>() - .HasOne(x => x.RatingType) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.Rating>("RatingSource_RatingType_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>() - .ToTable("RatingType") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>() - .Property(t => t.Name) - .HasMaxLength(1024) - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>() - .Property(t => t.MaximumValue) - .IsRequired() - .HasField("_MaximumValue") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>() - .Property(t => t.MinimumValue) - .IsRequired() - .HasField("_MinimumValue") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.RatingSource>() - .HasOne(x => x.Source) - .WithOne() - .HasForeignKey<global::Jellyfin.Data.Entities.RatingSource>("MetadataProviderId_Source_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>() - .ToTable("Release") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>() - .Property(t => t.Id) - .IsRequired() - .HasField("_Id") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>() - .Property(t => t.Name) - .HasMaxLength(1024) - .IsRequired() - .HasField("_Name") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>() - .Property(t => t.Timestamp) - .IsRequired() - .HasField("_Timestamp") - .UsePropertyAccessMode(PropertyAccessMode.Property) - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>() - .HasMany(x => x.MediaFiles) - .WithOne() - .HasForeignKey("MediaFile_MediaFiles_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Release>() - .HasMany(x => x.Chapters) - .WithOne() - .HasForeignKey("Chapter_Chapters_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Season>() - .Property(t => t.SeasonNumber) - .HasField("_SeasonNumber") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Season>() - .HasMany(x => x.SeasonMetadata) - .WithOne() - .HasForeignKey("SeasonMetadata_SeasonMetadata_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Season>() - .HasMany(x => x.Episodes) - .WithOne() - .HasForeignKey("Episode_Episodes_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.SeasonMetadata>() - .Property(t => t.Outline) - .HasMaxLength(1024) - .HasField("_Outline") - .UsePropertyAccessMode(PropertyAccessMode.Property); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>() - .Property(t => t.AirsDayOfWeek) - .HasField("_AirsDayOfWeek") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>() - .Property(t => t.AirsTime) - .HasField("_AirsTime") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>() - .Property(t => t.FirstAired) - .HasField("_FirstAired") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>() - .HasMany(x => x.SeriesMetadata) - .WithOne() - .HasForeignKey("SeriesMetadata_SeriesMetadata_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Series>() - .HasMany(x => x.Seasons) - .WithOne() - .HasForeignKey("Season_Seasons_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>() - .Property(t => t.Outline) - .HasMaxLength(1024) - .HasField("_Outline") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>() - .Property(t => t.Plot) - .HasMaxLength(65535) - .HasField("_Plot") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>() - .Property(t => t.Tagline) - .HasMaxLength(1024) - .HasField("_Tagline") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>() - .Property(t => t.Country) - .HasMaxLength(2) - .HasField("_Country") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.SeriesMetadata>() - .HasMany(x => x.Networks) - .WithOne() - .HasForeignKey("Company_Networks_Id") - .IsRequired(); - - modelBuilder.Entity<global::Jellyfin.Data.Entities.Track>() - .Property(t => t.TrackNumber) - .HasField("_TrackNumber") - .UsePropertyAccessMode(PropertyAccessMode.Property); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Track>() - .HasMany(x => x.Releases) - .WithOne() - .HasForeignKey("Release_Releases_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.Track>() - .HasMany(x => x.TrackMetadata) - .WithOne() - .HasForeignKey("TrackMetadata_TrackMetadata_Id") - .IsRequired(); - - - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .ToTable("Users") - .HasKey(t => t.Id); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.Id) - .IsRequired() - .ValueGeneratedOnAdd(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.LastLoginTimestamp) - .IsRequired() - .IsRowVersion(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.Username) - .HasMaxLength(255) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.Password) - .HasMaxLength(65535); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.MustUpdatePassword) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.AudioLanguagePreference) - .HasMaxLength(255) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.AuthenticationProviderId) - .HasMaxLength(255) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.GroupedFolders) - .HasMaxLength(65535); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.InvalidLoginAttemptCount) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.LatestItemExcludes) - .HasMaxLength(65535); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.MyMediaExcludes) - .HasMaxLength(65535); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.OrderedViews) - .HasMaxLength(65535); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.SubtitleMode) - .HasMaxLength(255) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.PlayDefaultAudioTrack) - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .Property(t => t.SubtitleLanguagePrefernce) - .HasMaxLength(255); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .HasMany(x => x.Groups) - .WithOne() - .HasForeignKey("Group_Groups_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .HasMany(x => x.Permissions) - .WithOne() - .HasForeignKey("Permission_Permissions_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .HasMany(x => x.ProviderMappings) - .WithOne() - .HasForeignKey("ProviderMapping_ProviderMappings_Id") - .IsRequired(); - modelBuilder.Entity<global::Jellyfin.Data.Entities.User>() - .HasMany(x => x.Preferences) - .WithOne() - .HasForeignKey("Preference_Preferences_Id") - .IsRequired(); - - OnModelCreatedImpl(modelBuilder); - } - } -} diff --git a/Jellyfin.Data/Entities/Artwork.cs b/Jellyfin.Data/Entities/Artwork.cs index be13686dc..bf3029368 100644 --- a/Jellyfin.Data/Entities/Artwork.cs +++ b/Jellyfin.Data/Entities/Artwork.cs @@ -1,208 +1,195 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Artwork - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Artwork() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Artwork CreateArtworkUnsafe() - { - return new Artwork(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="path"></param> - /// <param name="kind"></param> - /// <param name="_metadata0"></param> - /// <param name="_personrole1"></param> - public Artwork(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1) - { - if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); - this.Path = path; - - this.Kind = kind; - - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); - _metadata0.Artwork.Add(this); - - if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1)); - _personrole1.Artwork = this; - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="path"></param> - /// <param name="kind"></param> - /// <param name="_metadata0"></param> - /// <param name="_personrole1"></param> - public static Artwork Create(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1) - { - return new Artwork(path, kind, _metadata0, _personrole1); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class Artwork + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Artwork() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Artwork CreateArtworkUnsafe() + { + return new Artwork(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="path"></param> + /// <param name="kind"></param> + /// <param name="_metadata0"></param> + /// <param name="_personrole1"></param> + public Artwork(string path, Enums.ArtKind kind, Metadata _metadata0, PersonRole _personrole1) + { + if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); + this.Path = path; + + this.Kind = kind; + + if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + _metadata0.Artwork.Add(this); + + if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1)); + _personrole1.Artwork = this; + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="path"></param> + /// <param name="kind"></param> + /// <param name="_metadata0"></param> + /// <param name="_personrole1"></param> + public static Artwork Create(string path, Enums.ArtKind kind, Metadata _metadata0, PersonRole _personrole1) + { + return new Artwork(path, kind, _metadata0, _personrole1); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for Path + /// </summary> + protected string _Path; + /// <summary> + /// When provided in a partial class, allows value of Path to be changed before setting. + /// </summary> + partial void SetPath(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Path to be changed before returning. + /// </summary> + partial void GetPath(ref string result); + + /// <summary> + /// Required, Max length = 65535 + /// </summary> + [Required] + [MaxLength(65535)] + [StringLength(65535)] + public string Path + { + get + { + string value = _Path; + GetPath(ref value); + return (_Path = value); + } + set { - _Id = value; + string oldValue = _Path; + SetPath(oldValue, ref value); + if (oldValue != value) + { + _Path = value; + } } - } - } - - /// <summary> - /// Backing field for Path - /// </summary> - protected string _Path; - /// <summary> - /// When provided in a partial class, allows value of Path to be changed before setting. - /// </summary> - partial void SetPath(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Path to be changed before returning. - /// </summary> - partial void GetPath(ref string result); - - /// <summary> - /// Required, Max length = 65535 - /// </summary> - [Required] - [MaxLength(65535)] - [StringLength(65535)] - public string Path - { - get - { - string value = _Path; - GetPath(ref value); - return (_Path = value); - } - set - { - string oldValue = _Path; - SetPath(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Kind + /// </summary> + internal Enums.ArtKind _Kind; + /// <summary> + /// When provided in a partial class, allows value of Kind to be changed before setting. + /// </summary> + partial void SetKind(Enums.ArtKind oldValue, ref Enums.ArtKind newValue); + /// <summary> + /// When provided in a partial class, allows value of Kind to be changed before returning. + /// </summary> + partial void GetKind(ref Enums.ArtKind result); + + /// <summary> + /// Indexed, Required + /// </summary> + [Required] + public Enums.ArtKind Kind + { + get { - _Path = value; + Enums.ArtKind value = _Kind; + GetKind(ref value); + return (_Kind = value); } - } - } - - /// <summary> - /// Backing field for Kind - /// </summary> - internal global::Jellyfin.Data.Enums.ArtKind _Kind; - /// <summary> - /// When provided in a partial class, allows value of Kind to be changed before setting. - /// </summary> - partial void SetKind(global::Jellyfin.Data.Enums.ArtKind oldValue, ref global::Jellyfin.Data.Enums.ArtKind newValue); - /// <summary> - /// When provided in a partial class, allows value of Kind to be changed before returning. - /// </summary> - partial void GetKind(ref global::Jellyfin.Data.Enums.ArtKind result); - - /// <summary> - /// Indexed, Required - /// </summary> - [Required] - public global::Jellyfin.Data.Enums.ArtKind Kind - { - get - { - global::Jellyfin.Data.Enums.ArtKind value = _Kind; - GetKind(ref value); - return (_Kind = value); - } - set - { - global::Jellyfin.Data.Enums.ArtKind oldValue = _Kind; - SetKind(oldValue, ref value); - if (oldValue != value) + set { - _Kind = value; + Enums.ArtKind oldValue = _Kind; + SetKind(oldValue, ref value); + if (oldValue != value) + { + _Kind = value; + } } - } - } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Book.cs b/Jellyfin.Data/Entities/Book.cs index 30c89ae5c..42d24e31d 100644 --- a/Jellyfin.Data/Entities/Book.cs +++ b/Jellyfin.Data/Entities/Book.cs @@ -1,84 +1,69 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Book: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); + public partial class Book : LibraryItem + { + partial void Init(); - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Book(): base() - { - BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>(); - Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Book() + { + BookMetadata = new HashSet<BookMetadata>(); + Releases = new HashSet<Release>(); - Init(); - } + Init(); + } - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Book CreateBookUnsafe() - { - return new Book(); - } + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Book CreateBookUnsafe() + { + return new Book(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public Book(Guid urlid, DateTime dateadded) - { - this.UrlId = urlid; + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public Book(Guid urlid, DateTime dateadded) + { + this.UrlId = urlid; - this.BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>(); - this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); + this.BookMetadata = new HashSet<BookMetadata>(); + this.Releases = new HashSet<Release>(); - Init(); - } + Init(); + } - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public static Book Create(Guid urlid, DateTime dateadded) - { - return new Book(urlid, dateadded); - } + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public static Book Create(Guid urlid, DateTime dateadded) + { + return new Book(urlid, dateadded); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.BookMetadata> BookMetadata { get; protected set; } + [ForeignKey("BookMetadata_BookMetadata_Id")] + public virtual ICollection<BookMetadata> BookMetadata { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; } + [ForeignKey("Release_Releases_Id")] + public virtual ICollection<Release> Releases { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/BookMetadata.cs b/Jellyfin.Data/Entities/BookMetadata.cs index 3a28244d6..d52fe7605 100644 --- a/Jellyfin.Data/Entities/BookMetadata.cs +++ b/Jellyfin.Data/Entities/BookMetadata.cs @@ -1,123 +1,107 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class BookMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected BookMetadata(): base() - { - Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static BookMetadata CreateBookMetadataUnsafe() - { - return new BookMetadata(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_book0"></param> - public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - if (_book0 == null) throw new ArgumentNullException(nameof(_book0)); - _book0.BookMetadata.Add(this); - - this.Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_book0"></param> - public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0) - { - return new BookMetadata(title, language, dateadded, datemodified, _book0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for ISBN - /// </summary> - protected long? _ISBN; - /// <summary> - /// When provided in a partial class, allows value of ISBN to be changed before setting. - /// </summary> - partial void SetISBN(long? oldValue, ref long? newValue); - /// <summary> - /// When provided in a partial class, allows value of ISBN to be changed before returning. - /// </summary> - partial void GetISBN(ref long? result); - - public long? ISBN - { - get - { - long? value = _ISBN; - GetISBN(ref value); - return (_ISBN = value); - } - set - { - long? oldValue = _ISBN; - SetISBN(oldValue, ref value); - if (oldValue != value) + public partial class BookMetadata : Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected BookMetadata() + { + Publishers = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static BookMetadata CreateBookMetadataUnsafe() + { + return new BookMetadata(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_book0"></param> + public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + if (_book0 == null) throw new ArgumentNullException(nameof(_book0)); + _book0.BookMetadata.Add(this); + + this.Publishers = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_book0"></param> + public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0) + { + return new BookMetadata(title, language, dateadded, datemodified, _book0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for ISBN + /// </summary> + protected long? _ISBN; + /// <summary> + /// When provided in a partial class, allows value of ISBN to be changed before setting. + /// </summary> + partial void SetISBN(long? oldValue, ref long? newValue); + /// <summary> + /// When provided in a partial class, allows value of ISBN to be changed before returning. + /// </summary> + partial void GetISBN(ref long? result); + + public long? ISBN + { + get + { + long? value = _ISBN; + GetISBN(ref value); + return (_ISBN = value); + } + set { - _ISBN = value; + long? oldValue = _ISBN; + SetISBN(oldValue, ref value); + if (oldValue != value) + { + _ISBN = value; + } } - } - } + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.Company> Publishers { get; protected set; } + [ForeignKey("Company_Publishers_Id")] + public virtual ICollection<Company> Publishers { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/Chapter.cs b/Jellyfin.Data/Entities/Chapter.cs index 21a5dd73e..d48cb9b62 100644 --- a/Jellyfin.Data/Entities/Chapter.cs +++ b/Jellyfin.Data/Entities/Chapter.cs @@ -1,274 +1,263 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Chapter - { - partial void Init(); + public partial class Chapter + { + partial void Init(); - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Chapter() - { - Init(); - } + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Chapter() + { + Init(); + } - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Chapter CreateChapterUnsafe() - { - return new Chapter(); - } + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Chapter CreateChapterUnsafe() + { + return new Chapter(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="timestart"></param> - /// <param name="_release0"></param> - public Chapter(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0) - { - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="timestart"></param> + /// <param name="_release0"></param> + public Chapter(string language, long timestart, Release _release0) + { + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; - this.TimeStart = timestart; + this.TimeStart = timestart; - if (_release0 == null) throw new ArgumentNullException(nameof(_release0)); - _release0.Chapters.Add(this); + if (_release0 == null) throw new ArgumentNullException(nameof(_release0)); + _release0.Chapters.Add(this); - Init(); - } + Init(); + } - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="timestart"></param> - /// <param name="_release0"></param> - public static Chapter Create(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0) - { - return new Chapter(language, timestart, _release0); - } + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="timestart"></param> + /// <param name="_release0"></param> + public static Chapter Create(string language, long timestart, Release _release0) + { + return new Chapter(language, timestart, _release0); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } + } - /// <summary> - /// Backing field for Name - /// </summary> - protected string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); + /// <summary> + /// Backing field for Name + /// </summary> + protected string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Name + { + get { - _Name = value; + string value = _Name; + GetName(ref value); + return (_Name = value); } - } - } + set + { + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } + } + } - /// <summary> - /// Backing field for Language - /// </summary> - protected string _Language; - /// <summary> - /// When provided in a partial class, allows value of Language to be changed before setting. - /// </summary> - partial void SetLanguage(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Language to be changed before returning. - /// </summary> - partial void GetLanguage(ref string result); + /// <summary> + /// Backing field for Language + /// </summary> + protected string _Language; + /// <summary> + /// When provided in a partial class, allows value of Language to be changed before setting. + /// </summary> + partial void SetLanguage(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Language to be changed before returning. + /// </summary> + partial void GetLanguage(ref string result); - /// <summary> - /// Required, Min length = 3, Max length = 3 - /// ISO-639-3 3-character language codes - /// </summary> - [Required] - [MinLength(3)] - [MaxLength(3)] - [StringLength(3)] - public string Language - { - get - { - string value = _Language; - GetLanguage(ref value); - return (_Language = value); - } - set - { - string oldValue = _Language; - SetLanguage(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Required, Min length = 3, Max length = 3 + /// ISO-639-3 3-character language codes + /// </summary> + [Required] + [MinLength(3)] + [MaxLength(3)] + [StringLength(3)] + public string Language + { + get + { + string value = _Language; + GetLanguage(ref value); + return (_Language = value); + } + set { - _Language = value; + string oldValue = _Language; + SetLanguage(oldValue, ref value); + if (oldValue != value) + { + _Language = value; + } } - } - } + } - /// <summary> - /// Backing field for TimeStart - /// </summary> - protected long _TimeStart; - /// <summary> - /// When provided in a partial class, allows value of TimeStart to be changed before setting. - /// </summary> - partial void SetTimeStart(long oldValue, ref long newValue); - /// <summary> - /// When provided in a partial class, allows value of TimeStart to be changed before returning. - /// </summary> - partial void GetTimeStart(ref long result); + /// <summary> + /// Backing field for TimeStart + /// </summary> + protected long _TimeStart; + /// <summary> + /// When provided in a partial class, allows value of TimeStart to be changed before setting. + /// </summary> + partial void SetTimeStart(long oldValue, ref long newValue); + /// <summary> + /// When provided in a partial class, allows value of TimeStart to be changed before returning. + /// </summary> + partial void GetTimeStart(ref long result); - /// <summary> - /// Required - /// </summary> - [Required] - public long TimeStart - { - get - { - long value = _TimeStart; - GetTimeStart(ref value); - return (_TimeStart = value); - } - set - { - long oldValue = _TimeStart; - SetTimeStart(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Required + /// </summary> + [Required] + public long TimeStart + { + get + { + long value = _TimeStart; + GetTimeStart(ref value); + return (_TimeStart = value); + } + set { - _TimeStart = value; + long oldValue = _TimeStart; + SetTimeStart(oldValue, ref value); + if (oldValue != value) + { + _TimeStart = value; + } } - } - } + } - /// <summary> - /// Backing field for TimeEnd - /// </summary> - protected long? _TimeEnd; - /// <summary> - /// When provided in a partial class, allows value of TimeEnd to be changed before setting. - /// </summary> - partial void SetTimeEnd(long? oldValue, ref long? newValue); - /// <summary> - /// When provided in a partial class, allows value of TimeEnd to be changed before returning. - /// </summary> - partial void GetTimeEnd(ref long? result); + /// <summary> + /// Backing field for TimeEnd + /// </summary> + protected long? _TimeEnd; + /// <summary> + /// When provided in a partial class, allows value of TimeEnd to be changed before setting. + /// </summary> + partial void SetTimeEnd(long? oldValue, ref long? newValue); + /// <summary> + /// When provided in a partial class, allows value of TimeEnd to be changed before returning. + /// </summary> + partial void GetTimeEnd(ref long? result); - public long? TimeEnd - { - get - { - long? value = _TimeEnd; - GetTimeEnd(ref value); - return (_TimeEnd = value); - } - set - { - long? oldValue = _TimeEnd; - SetTimeEnd(oldValue, ref value); - if (oldValue != value) + public long? TimeEnd + { + get { - _TimeEnd = value; + long? value = _TimeEnd; + GetTimeEnd(ref value); + return (_TimeEnd = value); } - } - } + set + { + long? oldValue = _TimeEnd; + SetTimeEnd(oldValue, ref value); + if (oldValue != value) + { + _TimeEnd = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Collection.cs b/Jellyfin.Data/Entities/Collection.cs index 68979eb2f..e2fa3a5bd 100644 --- a/Jellyfin.Data/Entities/Collection.cs +++ b/Jellyfin.Data/Entities/Collection.cs @@ -1,131 +1,120 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Collection - { - partial void Init(); + public partial class Collection + { + partial void Init(); - /// <summary> - /// Default constructor - /// </summary> - public Collection() - { - CollectionItem = new System.Collections.Generic.LinkedList<global::Jellyfin.Data.Entities.CollectionItem>(); + /// <summary> + /// Default constructor + /// </summary> + public Collection() + { + CollectionItem = new LinkedList<CollectionItem>(); - Init(); - } + Init(); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } + } - /// <summary> - /// Backing field for Name - /// </summary> - protected string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); + /// <summary> + /// Backing field for Name + /// </summary> + protected string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Name + { + get + { + string value = _Name; + GetName(ref value); + return (_Name = value); + } + set { - _Name = value; + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } } - } - } + } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /************************************************************************* - * Navigation properties - *************************************************************************/ + public void OnSavingChanges() + { + RowVersion++; + } - public virtual ICollection<global::Jellyfin.Data.Entities.CollectionItem> CollectionItem { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("CollectionItem_CollectionItem_Id")] + public virtual ICollection<CollectionItem> CollectionItem { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/CollectionItem.cs b/Jellyfin.Data/Entities/CollectionItem.cs index 8e575e0a2..4a3d06639 100644 --- a/Jellyfin.Data/Entities/CollectionItem.cs +++ b/Jellyfin.Data/Entities/CollectionItem.cs @@ -1,151 +1,143 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class CollectionItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected CollectionItem() - { - // NOTE: This class has one-to-one associations with CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static CollectionItem CreateCollectionItemUnsafe() - { - return new CollectionItem(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="_collection0"></param> - /// <param name="_collectionitem1"></param> - /// <param name="_collectionitem2"></param> - public CollectionItem(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2) - { - // NOTE: This class has one-to-one associations with CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0)); - _collection0.CollectionItem.Add(this); - - if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1)); - _collectionitem1.Next = this; - - if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2)); - _collectionitem2.Previous = this; - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="_collection0"></param> - /// <param name="_collectionitem1"></param> - /// <param name="_collectionitem2"></param> - public static CollectionItem Create(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2) - { - return new CollectionItem(_collection0, _collectionitem1, _collectionitem2); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class CollectionItem + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected CollectionItem() + { + // NOTE: This class has one-to-one associations with CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static CollectionItem CreateCollectionItemUnsafe() + { + return new CollectionItem(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="_collection0"></param> + /// <param name="_collectionitem1"></param> + /// <param name="_collectionitem2"></param> + public CollectionItem(Collection _collection0, CollectionItem _collectionitem1, CollectionItem _collectionitem2) + { + // NOTE: This class has one-to-one associations with CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0)); + _collection0.CollectionItem.Add(this); + + if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1)); + _collectionitem1.Next = this; + + if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2)); + _collectionitem2.Previous = this; + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="_collection0"></param> + /// <param name="_collectionitem1"></param> + /// <param name="_collectionitem2"></param> + public static CollectionItem Create(Collection _collection0, CollectionItem _collectionitem1, CollectionItem _collectionitem2) + { + return new CollectionItem(_collection0, _collectionitem1, _collectionitem2); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - /// <summary> - /// Required - /// </summary> - public virtual global::Jellyfin.Data.Entities.LibraryItem LibraryItem { get; set; } - - /// <remarks> - /// TODO check if this properly updated dependant and has the proper principal relationship - /// </remarks> - public virtual global::Jellyfin.Data.Entities.CollectionItem Next { get; set; } - - /// <remarks> - /// TODO check if this properly updated dependant and has the proper principal relationship - /// </remarks> - public virtual global::Jellyfin.Data.Entities.CollectionItem Previous { get; set; } - - } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + /// <summary> + /// Required + /// </summary> + [ForeignKey("LibraryItem_Id")] + public virtual LibraryItem LibraryItem { get; set; } + + /// <remarks> + /// TODO check if this properly updated dependant and has the proper principal relationship + /// </remarks> + [ForeignKey("CollectionItem_Next_Id")] + public virtual CollectionItem Next { get; set; } + + /// <remarks> + /// TODO check if this properly updated dependant and has the proper principal relationship + /// </remarks> + [ForeignKey("CollectionItem_Previous_Id")] + public virtual CollectionItem Previous { get; set; } + + } } diff --git a/Jellyfin.Data/Entities/Company.cs b/Jellyfin.Data/Entities/Company.cs index 444ae9c56..0650271c6 100644 --- a/Jellyfin.Data/Entities/Company.cs +++ b/Jellyfin.Data/Entities/Company.cs @@ -1,147 +1,137 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Company - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Company() - { - CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Company CreateCompanyUnsafe() - { - return new Company(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="_moviemetadata0"></param> - /// <param name="_seriesmetadata1"></param> - /// <param name="_musicalbummetadata2"></param> - /// <param name="_bookmetadata3"></param> - /// <param name="_company4"></param> - public Company(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4) - { - if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0)); - _moviemetadata0.Studios.Add(this); - - if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1)); - _seriesmetadata1.Networks.Add(this); - - if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2)); - _musicalbummetadata2.Labels.Add(this); - - if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3)); - _bookmetadata3.Publishers.Add(this); - - if (_company4 == null) throw new ArgumentNullException(nameof(_company4)); - _company4.Parent = this; - - this.CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="_moviemetadata0"></param> - /// <param name="_seriesmetadata1"></param> - /// <param name="_musicalbummetadata2"></param> - /// <param name="_bookmetadata3"></param> - /// <param name="_company4"></param> - public static Company Create(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4) - { - return new Company(_moviemetadata0, _seriesmetadata1, _musicalbummetadata2, _bookmetadata3, _company4); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class Company + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Company() + { + CompanyMetadata = new HashSet<CompanyMetadata>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Company CreateCompanyUnsafe() + { + return new Company(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="_moviemetadata0"></param> + /// <param name="_seriesmetadata1"></param> + /// <param name="_musicalbummetadata2"></param> + /// <param name="_bookmetadata3"></param> + /// <param name="_company4"></param> + public Company(MovieMetadata _moviemetadata0, SeriesMetadata _seriesmetadata1, MusicAlbumMetadata _musicalbummetadata2, BookMetadata _bookmetadata3, Company _company4) + { + if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0)); + _moviemetadata0.Studios.Add(this); + + if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1)); + _seriesmetadata1.Networks.Add(this); + + if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2)); + _musicalbummetadata2.Labels.Add(this); + + if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3)); + _bookmetadata3.Publishers.Add(this); + + if (_company4 == null) throw new ArgumentNullException(nameof(_company4)); + _company4.Parent = this; + + this.CompanyMetadata = new HashSet<CompanyMetadata>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="_moviemetadata0"></param> + /// <param name="_seriesmetadata1"></param> + /// <param name="_musicalbummetadata2"></param> + /// <param name="_bookmetadata3"></param> + /// <param name="_company4"></param> + public static Company Create(MovieMetadata _moviemetadata0, SeriesMetadata _seriesmetadata1, MusicAlbumMetadata _musicalbummetadata2, BookMetadata _bookmetadata3, Company _company4) + { + return new Company(_moviemetadata0, _seriesmetadata1, _musicalbummetadata2, _bookmetadata3, _company4); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get { - _Id = value; + int value = _Id; + GetId(ref value); + return (_Id = value); } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - public virtual ICollection<global::Jellyfin.Data.Entities.CompanyMetadata> CompanyMetadata { get; protected set; } - - public virtual global::Jellyfin.Data.Entities.Company Parent { get; set; } - - } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("CompanyMetadata_CompanyMetadata_Id")] + public virtual ICollection<CompanyMetadata> CompanyMetadata { get; protected set; } + [ForeignKey("Company_Parent_Id")] + public virtual Company Parent { get; set; } + + } } diff --git a/Jellyfin.Data/Entities/CompanyMetadata.cs b/Jellyfin.Data/Entities/CompanyMetadata.cs index 6d636e884..b3ec9c1a7 100644 --- a/Jellyfin.Data/Entities/CompanyMetadata.cs +++ b/Jellyfin.Data/Entities/CompanyMetadata.cs @@ -1,234 +1,216 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class CompanyMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected CompanyMetadata(): base() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static CompanyMetadata CreateCompanyMetadataUnsafe() - { - return new CompanyMetadata(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_company0"></param> - public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - if (_company0 == null) throw new ArgumentNullException(nameof(_company0)); - _company0.CompanyMetadata.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_company0"></param> - public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0) - { - return new CompanyMetadata(title, language, dateadded, datemodified, _company0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Description - /// </summary> - protected string _Description; - /// <summary> - /// When provided in a partial class, allows value of Description to be changed before setting. - /// </summary> - partial void SetDescription(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Description to be changed before returning. - /// </summary> - partial void GetDescription(ref string result); - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string Description - { - get - { - string value = _Description; - GetDescription(ref value); - return (_Description = value); - } - set - { - string oldValue = _Description; - SetDescription(oldValue, ref value); - if (oldValue != value) + public partial class CompanyMetadata : Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected CompanyMetadata() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static CompanyMetadata CreateCompanyMetadataUnsafe() + { + return new CompanyMetadata(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_company0"></param> + public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + if (_company0 == null) throw new ArgumentNullException(nameof(_company0)); + _company0.CompanyMetadata.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_company0"></param> + public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0) + { + return new CompanyMetadata(title, language, dateadded, datemodified, _company0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Description + /// </summary> + protected string _Description; + /// <summary> + /// When provided in a partial class, allows value of Description to be changed before setting. + /// </summary> + partial void SetDescription(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Description to be changed before returning. + /// </summary> + partial void GetDescription(ref string result); + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string Description + { + get + { + string value = _Description; + GetDescription(ref value); + return (_Description = value); + } + set + { + string oldValue = _Description; + SetDescription(oldValue, ref value); + if (oldValue != value) + { + _Description = value; + } + } + } + + /// <summary> + /// Backing field for Headquarters + /// </summary> + protected string _Headquarters; + /// <summary> + /// When provided in a partial class, allows value of Headquarters to be changed before setting. + /// </summary> + partial void SetHeadquarters(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Headquarters to be changed before returning. + /// </summary> + partial void GetHeadquarters(ref string result); + + /// <summary> + /// Max length = 255 + /// </summary> + [MaxLength(255)] + [StringLength(255)] + public string Headquarters + { + get + { + string value = _Headquarters; + GetHeadquarters(ref value); + return (_Headquarters = value); + } + set + { + string oldValue = _Headquarters; + SetHeadquarters(oldValue, ref value); + if (oldValue != value) + { + _Headquarters = value; + } + } + } + + /// <summary> + /// Backing field for Country + /// </summary> + protected string _Country; + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before setting. + /// </summary> + partial void SetCountry(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before returning. + /// </summary> + partial void GetCountry(ref string result); + + /// <summary> + /// Max length = 2 + /// </summary> + [MaxLength(2)] + [StringLength(2)] + public string Country + { + get { - _Description = value; + string value = _Country; + GetCountry(ref value); + return (_Country = value); } - } - } - - /// <summary> - /// Backing field for Headquarters - /// </summary> - protected string _Headquarters; - /// <summary> - /// When provided in a partial class, allows value of Headquarters to be changed before setting. - /// </summary> - partial void SetHeadquarters(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Headquarters to be changed before returning. - /// </summary> - partial void GetHeadquarters(ref string result); - - /// <summary> - /// Max length = 255 - /// </summary> - [MaxLength(255)] - [StringLength(255)] - public string Headquarters - { - get - { - string value = _Headquarters; - GetHeadquarters(ref value); - return (_Headquarters = value); - } - set - { - string oldValue = _Headquarters; - SetHeadquarters(oldValue, ref value); - if (oldValue != value) + set { - _Headquarters = value; + string oldValue = _Country; + SetCountry(oldValue, ref value); + if (oldValue != value) + { + _Country = value; + } } - } - } - - /// <summary> - /// Backing field for Country - /// </summary> - protected string _Country; - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before setting. - /// </summary> - partial void SetCountry(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before returning. - /// </summary> - partial void GetCountry(ref string result); - - /// <summary> - /// Max length = 2 - /// </summary> - [MaxLength(2)] - [StringLength(2)] - public string Country - { - get - { - string value = _Country; - GetCountry(ref value); - return (_Country = value); - } - set - { - string oldValue = _Country; - SetCountry(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Homepage + /// </summary> + protected string _Homepage; + /// <summary> + /// When provided in a partial class, allows value of Homepage to be changed before setting. + /// </summary> + partial void SetHomepage(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Homepage to be changed before returning. + /// </summary> + partial void GetHomepage(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Homepage + { + get { - _Country = value; + string value = _Homepage; + GetHomepage(ref value); + return (_Homepage = value); } - } - } - - /// <summary> - /// Backing field for Homepage - /// </summary> - protected string _Homepage; - /// <summary> - /// When provided in a partial class, allows value of Homepage to be changed before setting. - /// </summary> - partial void SetHomepage(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Homepage to be changed before returning. - /// </summary> - partial void GetHomepage(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Homepage - { - get - { - string value = _Homepage; - GetHomepage(ref value); - return (_Homepage = value); - } - set - { - string oldValue = _Homepage; - SetHomepage(oldValue, ref value); - if (oldValue != value) + set { - _Homepage = value; + string oldValue = _Homepage; + SetHomepage(oldValue, ref value); + if (oldValue != value) + { + _Homepage = value; + } } - } - } + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/CustomItem.cs b/Jellyfin.Data/Entities/CustomItem.cs index eb6d2752d..2006717bf 100644 --- a/Jellyfin.Data/Entities/CustomItem.cs +++ b/Jellyfin.Data/Entities/CustomItem.cs @@ -1,84 +1,68 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class CustomItem: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected CustomItem(): base() - { - CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>(); - Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); + public partial class CustomItem : LibraryItem + { + partial void Init(); - Init(); - } + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected CustomItem() + { + CustomItemMetadata = new HashSet<CustomItemMetadata>(); + Releases = new HashSet<Release>(); - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static CustomItem CreateCustomItemUnsafe() - { - return new CustomItem(); - } + Init(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public CustomItem(Guid urlid, DateTime dateadded) - { - this.UrlId = urlid; + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static CustomItem CreateCustomItemUnsafe() + { + return new CustomItem(); + } - this.CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>(); - this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public CustomItem(Guid urlid, DateTime dateadded) + { + this.UrlId = urlid; - Init(); - } + this.CustomItemMetadata = new HashSet<CustomItemMetadata>(); + this.Releases = new HashSet<Release>(); - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public static CustomItem Create(Guid urlid, DateTime dateadded) - { - return new CustomItem(urlid, dateadded); - } + Init(); + } - /************************************************************************* - * Properties - *************************************************************************/ + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public static CustomItem Create(Guid urlid, DateTime dateadded) + { + return new CustomItem(urlid, dateadded); + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.CustomItemMetadata> CustomItemMetadata { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("CustomItemMetadata_CustomItemMetadata_Id")] + public virtual ICollection<CustomItemMetadata> CustomItemMetadata { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; } + [ForeignKey("Release_Releases_Id")] + public virtual ICollection<Release> Releases { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/CustomItemMetadata.cs b/Jellyfin.Data/Entities/CustomItemMetadata.cs index f2c15d3fe..e09e4467a 100644 --- a/Jellyfin.Data/Entities/CustomItemMetadata.cs +++ b/Jellyfin.Data/Entities/CustomItemMetadata.cs @@ -1,86 +1,67 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class CustomItemMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); + public partial class CustomItemMetadata : Metadata + { + partial void Init(); - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected CustomItemMetadata(): base() - { - Init(); - } + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected CustomItemMetadata() + { + Init(); + } - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static CustomItemMetadata CreateCustomItemMetadataUnsafe() - { - return new CustomItemMetadata(); - } + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static CustomItemMetadata CreateCustomItemMetadataUnsafe() + { + return new CustomItemMetadata(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_customitem0"></param> - public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_customitem0"></param> + public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; - if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0)); - _customitem0.CustomItemMetadata.Add(this); + if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0)); + _customitem0.CustomItemMetadata.Add(this); - Init(); - } + Init(); + } - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_customitem0"></param> - public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0) - { - return new CustomItemMetadata(title, language, dateadded, datemodified, _customitem0); - } + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_customitem0"></param> + public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0) + { + return new CustomItemMetadata(title, language, dateadded, datemodified, _customitem0); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Episode.cs b/Jellyfin.Data/Entities/Episode.cs index 3a23f0976..6f6baa14d 100644 --- a/Jellyfin.Data/Entities/Episode.cs +++ b/Jellyfin.Data/Entities/Episode.cs @@ -1,127 +1,110 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Episode: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Episode(): base() - { - // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); - EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Episode CreateEpisodeUnsafe() - { - return new Episode(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - /// <param name="_season0"></param> - public Episode(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0) - { - // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - this.UrlId = urlid; - - if (_season0 == null) throw new ArgumentNullException(nameof(_season0)); - _season0.Episodes.Add(this); - - this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); - this.EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - /// <param name="_season0"></param> - public static Episode Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0) - { - return new Episode(urlid, dateadded, _season0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for EpisodeNumber - /// </summary> - protected int? _EpisodeNumber; - /// <summary> - /// When provided in a partial class, allows value of EpisodeNumber to be changed before setting. - /// </summary> - partial void SetEpisodeNumber(int? oldValue, ref int? newValue); - /// <summary> - /// When provided in a partial class, allows value of EpisodeNumber to be changed before returning. - /// </summary> - partial void GetEpisodeNumber(ref int? result); - - public int? EpisodeNumber - { - get - { - int? value = _EpisodeNumber; - GetEpisodeNumber(ref value); - return (_EpisodeNumber = value); - } - set - { - int? oldValue = _EpisodeNumber; - SetEpisodeNumber(oldValue, ref value); - if (oldValue != value) + public partial class Episode : LibraryItem + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Episode() + { + // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + Releases = new HashSet<Release>(); + EpisodeMetadata = new HashSet<EpisodeMetadata>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Episode CreateEpisodeUnsafe() + { + return new Episode(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + /// <param name="_season0"></param> + public Episode(Guid urlid, DateTime dateadded, Season _season0) + { + // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + this.UrlId = urlid; + + if (_season0 == null) throw new ArgumentNullException(nameof(_season0)); + _season0.Episodes.Add(this); + + this.Releases = new HashSet<Release>(); + this.EpisodeMetadata = new HashSet<EpisodeMetadata>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + /// <param name="_season0"></param> + public static Episode Create(Guid urlid, DateTime dateadded, Season _season0) + { + return new Episode(urlid, dateadded, _season0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for EpisodeNumber + /// </summary> + protected int? _EpisodeNumber; + /// <summary> + /// When provided in a partial class, allows value of EpisodeNumber to be changed before setting. + /// </summary> + partial void SetEpisodeNumber(int? oldValue, ref int? newValue); + /// <summary> + /// When provided in a partial class, allows value of EpisodeNumber to be changed before returning. + /// </summary> + partial void GetEpisodeNumber(ref int? result); + + public int? EpisodeNumber + { + get { - _EpisodeNumber = value; + int? value = _EpisodeNumber; + GetEpisodeNumber(ref value); + return (_EpisodeNumber = value); } - } - } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; } + set + { + int? oldValue = _EpisodeNumber; + SetEpisodeNumber(oldValue, ref value); + if (oldValue != value) + { + _EpisodeNumber = value; + } + } + } - public virtual ICollection<global::Jellyfin.Data.Entities.EpisodeMetadata> EpisodeMetadata { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("Release_Releases_Id")] + public virtual ICollection<Release> Releases { get; protected set; } + [ForeignKey("EpisodeMetadata_EpisodeMetadata_Id")] + public virtual ICollection<EpisodeMetadata> EpisodeMetadata { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/EpisodeMetadata.cs b/Jellyfin.Data/Entities/EpisodeMetadata.cs index 963219140..e5431bf22 100644 --- a/Jellyfin.Data/Entities/EpisodeMetadata.cs +++ b/Jellyfin.Data/Entities/EpisodeMetadata.cs @@ -1,197 +1,179 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class EpisodeMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected EpisodeMetadata(): base() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static EpisodeMetadata CreateEpisodeMetadataUnsafe() - { - return new EpisodeMetadata(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_episode0"></param> - public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0)); - _episode0.EpisodeMetadata.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_episode0"></param> - public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0) - { - return new EpisodeMetadata(title, language, dateadded, datemodified, _episode0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Outline - /// </summary> - protected string _Outline; - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before setting. - /// </summary> - partial void SetOutline(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before returning. - /// </summary> - partial void GetOutline(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Outline - { - get - { - string value = _Outline; - GetOutline(ref value); - return (_Outline = value); - } - set - { - string oldValue = _Outline; - SetOutline(oldValue, ref value); - if (oldValue != value) + public partial class EpisodeMetadata : Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected EpisodeMetadata() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static EpisodeMetadata CreateEpisodeMetadataUnsafe() + { + return new EpisodeMetadata(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_episode0"></param> + public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0)); + _episode0.EpisodeMetadata.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_episode0"></param> + public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0) + { + return new EpisodeMetadata(title, language, dateadded, datemodified, _episode0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Outline + /// </summary> + protected string _Outline; + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before setting. + /// </summary> + partial void SetOutline(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before returning. + /// </summary> + partial void GetOutline(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Outline + { + get + { + string value = _Outline; + GetOutline(ref value); + return (_Outline = value); + } + set + { + string oldValue = _Outline; + SetOutline(oldValue, ref value); + if (oldValue != value) + { + _Outline = value; + } + } + } + + /// <summary> + /// Backing field for Plot + /// </summary> + protected string _Plot; + /// <summary> + /// When provided in a partial class, allows value of Plot to be changed before setting. + /// </summary> + partial void SetPlot(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Plot to be changed before returning. + /// </summary> + partial void GetPlot(ref string result); + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string Plot + { + get + { + string value = _Plot; + GetPlot(ref value); + return (_Plot = value); + } + set { - _Outline = value; + string oldValue = _Plot; + SetPlot(oldValue, ref value); + if (oldValue != value) + { + _Plot = value; + } } - } - } - - /// <summary> - /// Backing field for Plot - /// </summary> - protected string _Plot; - /// <summary> - /// When provided in a partial class, allows value of Plot to be changed before setting. - /// </summary> - partial void SetPlot(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Plot to be changed before returning. - /// </summary> - partial void GetPlot(ref string result); - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string Plot - { - get - { - string value = _Plot; - GetPlot(ref value); - return (_Plot = value); - } - set - { - string oldValue = _Plot; - SetPlot(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Tagline + /// </summary> + protected string _Tagline; + /// <summary> + /// When provided in a partial class, allows value of Tagline to be changed before setting. + /// </summary> + partial void SetTagline(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Tagline to be changed before returning. + /// </summary> + partial void GetTagline(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Tagline + { + get { - _Plot = value; + string value = _Tagline; + GetTagline(ref value); + return (_Tagline = value); } - } - } - - /// <summary> - /// Backing field for Tagline - /// </summary> - protected string _Tagline; - /// <summary> - /// When provided in a partial class, allows value of Tagline to be changed before setting. - /// </summary> - partial void SetTagline(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Tagline to be changed before returning. - /// </summary> - partial void GetTagline(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Tagline - { - get - { - string value = _Tagline; - GetTagline(ref value); - return (_Tagline = value); - } - set - { - string oldValue = _Tagline; - SetTagline(oldValue, ref value); - if (oldValue != value) + set { - _Tagline = value; + string oldValue = _Tagline; + SetTagline(oldValue, ref value); + if (oldValue != value) + { + _Tagline = value; + } } - } - } + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Genre.cs b/Jellyfin.Data/Entities/Genre.cs index 982600553..38f289a8e 100644 --- a/Jellyfin.Data/Entities/Genre.cs +++ b/Jellyfin.Data/Entities/Genre.cs @@ -1,163 +1,152 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Genre - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Genre() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Genre CreateGenreUnsafe() - { - return new Genre(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="name"></param> - /// <param name="_metadata0"></param> - public Genre(string name, global::Jellyfin.Data.Entities.Metadata _metadata0) - { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; - - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); - _metadata0.Genres.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="name"></param> - /// <param name="_metadata0"></param> - public static Genre Create(string name, global::Jellyfin.Data.Entities.Metadata _metadata0) - { - return new Genre(name, _metadata0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class Genre + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Genre() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Genre CreateGenreUnsafe() + { + return new Genre(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="name"></param> + /// <param name="_metadata0"></param> + public Genre(string name, Metadata _metadata0) + { + if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + this.Name = name; + + if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + _metadata0.Genres.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="name"></param> + /// <param name="_metadata0"></param> + public static Genre Create(string name, Metadata _metadata0) + { + return new Genre(name, _metadata0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } - - /// <summary> - /// Backing field for Name - /// </summary> - internal string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); - - /// <summary> - /// Indexed, Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Name + /// </summary> + internal string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); + + /// <summary> + /// Indexed, Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string Name + { + get { - _Name = value; + string value = _Name; + GetName(ref value); + return (_Name = value); } - } - } + set + { + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Group.cs b/Jellyfin.Data/Entities/Group.cs index ff19e9b01..54f9f4905 100644 --- a/Jellyfin.Data/Entities/Group.cs +++ b/Jellyfin.Data/Entities/Group.cs @@ -1,115 +1,109 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Group - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Group() - { - GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>(); - ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>(); - Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Group CreateGroupUnsafe() - { - return new Group(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="name"></param> - /// <param name="_user0"></param> - public Group(string name, global::Jellyfin.Data.Entities.User _user0) - { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; - - if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); - _user0.Groups.Add(this); - - this.GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>(); - this.ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>(); - this.Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="name"></param> - /// <param name="_user0"></param> - public static Group Create(string name, global::Jellyfin.Data.Entities.User _user0) - { - return new Group(name, _user0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id { get; protected set; } - - /// <summary> - /// Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string Name { get; set; } - - /// <summary> - /// Concurrency token - /// </summary> - [Timestamp] - public Byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - public virtual ICollection<global::Jellyfin.Data.Entities.Permission> GroupPermissions { get; protected set; } - - public virtual ICollection<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; protected set; } - - public virtual ICollection<global::Jellyfin.Data.Entities.Preference> Preferences { get; protected set; } - - } + public partial class Group + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Group() + { + GroupPermissions = new HashSet<Permission>(); + ProviderMappings = new HashSet<ProviderMapping>(); + Preferences = new HashSet<Preference>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Group CreateGroupUnsafe() + { + return new Group(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="name"></param> + /// <param name="_user0"></param> + public Group(string name, User _user0) + { + if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + this.Name = name; + + if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); + _user0.Groups.Add(this); + + this.GroupPermissions = new HashSet<Permission>(); + this.ProviderMappings = new HashSet<ProviderMapping>(); + this.Preferences = new HashSet<Preference>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="name"></param> + /// <param name="_user0"></param> + public static Group Create(string name, User _user0) + { + return new Group(name, _user0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; protected set; } + + /// <summary> + /// Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string Name { get; set; } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + [ForeignKey("Permission_GroupPermissions_Id")] + public virtual ICollection<Permission> GroupPermissions { get; protected set; } + + [ForeignKey("ProviderMapping_ProviderMappings_Id")] + public virtual ICollection<ProviderMapping> ProviderMappings { get; protected set; } + + [ForeignKey("Preference_Preferences_Id")] + public virtual ICollection<Preference> Preferences { get; protected set; } + + } } diff --git a/Jellyfin.Data/Entities/Library.cs b/Jellyfin.Data/Entities/Library.cs index 19ca14294..c11c09e91 100644 --- a/Jellyfin.Data/Entities/Library.cs +++ b/Jellyfin.Data/Entities/Library.cs @@ -1,158 +1,147 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Library - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Library() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Library CreateLibraryUnsafe() - { - return new Library(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="name"></param> - public Library(string name) - { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="name"></param> - public static Library Create(string name) - { - return new Library(name); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class Library + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Library() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Library CreateLibraryUnsafe() + { + return new Library(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="name"></param> + public Library(string name) + { + if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + this.Name = name; + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="name"></param> + public static Library Create(string name) + { + return new Library(name); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } - - /// <summary> - /// Backing field for Name - /// </summary> - protected string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); - - /// <summary> - /// Required, Max length = 1024 - /// </summary> - [Required] - [MaxLength(1024)] - [StringLength(1024)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Name + /// </summary> + protected string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); + + /// <summary> + /// Required, Max length = 1024 + /// </summary> + [Required] + [MaxLength(1024)] + [StringLength(1024)] + public string Name + { + get { - _Name = value; + string value = _Name; + GetName(ref value); + return (_Name = value); } - } - } + set + { + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/LibraryItem.cs b/Jellyfin.Data/Entities/LibraryItem.cs index 1987196d6..af6c640b9 100644 --- a/Jellyfin.Data/Entities/LibraryItem.cs +++ b/Jellyfin.Data/Entities/LibraryItem.cs @@ -1,180 +1,170 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public abstract partial class LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to being abstract. - /// </summary> - protected LibraryItem() - { - Init(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - protected LibraryItem(Guid urlid, DateTime dateadded) - { - this.UrlId = urlid; - - - Init(); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public abstract partial class LibraryItem + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to being abstract. + /// </summary> + protected LibraryItem() + { + Init(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + protected LibraryItem(Guid urlid, DateTime dateadded) + { + this.UrlId = urlid; + + + Init(); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for UrlId + /// </summary> + internal Guid _UrlId; + /// <summary> + /// When provided in a partial class, allows value of UrlId to be changed before setting. + /// </summary> + partial void SetUrlId(Guid oldValue, ref Guid newValue); + /// <summary> + /// When provided in a partial class, allows value of UrlId to be changed before returning. + /// </summary> + partial void GetUrlId(ref Guid result); + + /// <summary> + /// Indexed, Required + /// This is whats gets displayed in the Urls and API requests. This could also be a string. + /// </summary> + [Required] + public Guid UrlId + { + get + { + Guid value = _UrlId; + GetUrlId(ref value); + return (_UrlId = value); + } + set { - _Id = value; + Guid oldValue = _UrlId; + SetUrlId(oldValue, ref value); + if (oldValue != value) + { + _UrlId = value; + } } - } - } - - /// <summary> - /// Backing field for UrlId - /// </summary> - internal Guid _UrlId; - /// <summary> - /// When provided in a partial class, allows value of UrlId to be changed before setting. - /// </summary> - partial void SetUrlId(Guid oldValue, ref Guid newValue); - /// <summary> - /// When provided in a partial class, allows value of UrlId to be changed before returning. - /// </summary> - partial void GetUrlId(ref Guid result); - - /// <summary> - /// Indexed, Required - /// This is whats gets displayed in the Urls and API requests. This could also be a string. - /// </summary> - [Required] - public Guid UrlId - { - get - { - Guid value = _UrlId; - GetUrlId(ref value); - return (_UrlId = value); - } - set - { - Guid oldValue = _UrlId; - SetUrlId(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for DateAdded + /// </summary> + protected DateTime _DateAdded; + /// <summary> + /// When provided in a partial class, allows value of DateAdded to be changed before setting. + /// </summary> + partial void SetDateAdded(DateTime oldValue, ref DateTime newValue); + /// <summary> + /// When provided in a partial class, allows value of DateAdded to be changed before returning. + /// </summary> + partial void GetDateAdded(ref DateTime result); + + /// <summary> + /// Required + /// </summary> + [Required] + public DateTime DateAdded + { + get { - _UrlId = value; + DateTime value = _DateAdded; + GetDateAdded(ref value); + return (_DateAdded = value); } - } - } - - /// <summary> - /// Backing field for DateAdded - /// </summary> - protected DateTime _DateAdded; - /// <summary> - /// When provided in a partial class, allows value of DateAdded to be changed before setting. - /// </summary> - partial void SetDateAdded(DateTime oldValue, ref DateTime newValue); - /// <summary> - /// When provided in a partial class, allows value of DateAdded to be changed before returning. - /// </summary> - partial void GetDateAdded(ref DateTime result); - - /// <summary> - /// Required - /// </summary> - [Required] - public DateTime DateAdded - { - get - { - DateTime value = _DateAdded; - GetDateAdded(ref value); - return (_DateAdded = value); - } - internal set - { - DateTime oldValue = _DateAdded; - SetDateAdded(oldValue, ref value); - if (oldValue != value) + internal set { - _DateAdded = value; + DateTime oldValue = _DateAdded; + SetDateAdded(oldValue, ref value); + if (oldValue != value) + { + _DateAdded = value; + } } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - /// <summary> - /// Required - /// </summary> - public virtual global::Jellyfin.Data.Entities.LibraryRoot LibraryRoot { get; set; } - - } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + /// <summary> + /// Required + /// </summary> + [ForeignKey("LibraryRoot_Id")] + public virtual LibraryRoot LibraryRoot { get; set; } + + } } diff --git a/Jellyfin.Data/Entities/LibraryRoot.cs b/Jellyfin.Data/Entities/LibraryRoot.cs index 015fc4ea9..bbc23e1c9 100644 --- a/Jellyfin.Data/Entities/LibraryRoot.cs +++ b/Jellyfin.Data/Entities/LibraryRoot.cs @@ -1,202 +1,192 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class LibraryRoot - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected LibraryRoot() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static LibraryRoot CreateLibraryRootUnsafe() - { - return new LibraryRoot(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="path">Absolute Path</param> - public LibraryRoot(string path) - { - if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); - this.Path = path; - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="path">Absolute Path</param> - public static LibraryRoot Create(string path) - { - return new LibraryRoot(path); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class LibraryRoot + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected LibraryRoot() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static LibraryRoot CreateLibraryRootUnsafe() + { + return new LibraryRoot(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="path">Absolute Path</param> + public LibraryRoot(string path) + { + if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); + this.Path = path; + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="path">Absolute Path</param> + public static LibraryRoot Create(string path) + { + return new LibraryRoot(path); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for Path + /// </summary> + protected string _Path; + /// <summary> + /// When provided in a partial class, allows value of Path to be changed before setting. + /// </summary> + partial void SetPath(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Path to be changed before returning. + /// </summary> + partial void GetPath(ref string result); + + /// <summary> + /// Required, Max length = 65535 + /// Absolute Path + /// </summary> + [Required] + [MaxLength(65535)] + [StringLength(65535)] + public string Path + { + get + { + string value = _Path; + GetPath(ref value); + return (_Path = value); + } + set { - _Id = value; + string oldValue = _Path; + SetPath(oldValue, ref value); + if (oldValue != value) + { + _Path = value; + } } - } - } - - /// <summary> - /// Backing field for Path - /// </summary> - protected string _Path; - /// <summary> - /// When provided in a partial class, allows value of Path to be changed before setting. - /// </summary> - partial void SetPath(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Path to be changed before returning. - /// </summary> - partial void GetPath(ref string result); - - /// <summary> - /// Required, Max length = 65535 - /// Absolute Path - /// </summary> - [Required] - [MaxLength(65535)] - [StringLength(65535)] - public string Path - { - get - { - string value = _Path; - GetPath(ref value); - return (_Path = value); - } - set - { - string oldValue = _Path; - SetPath(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for NetworkPath + /// </summary> + protected string _NetworkPath; + /// <summary> + /// When provided in a partial class, allows value of NetworkPath to be changed before setting. + /// </summary> + partial void SetNetworkPath(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of NetworkPath to be changed before returning. + /// </summary> + partial void GetNetworkPath(ref string result); + + /// <summary> + /// Max length = 65535 + /// Absolute network path, for example for transcoding sattelites. + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string NetworkPath + { + get { - _Path = value; + string value = _NetworkPath; + GetNetworkPath(ref value); + return (_NetworkPath = value); } - } - } - - /// <summary> - /// Backing field for NetworkPath - /// </summary> - protected string _NetworkPath; - /// <summary> - /// When provided in a partial class, allows value of NetworkPath to be changed before setting. - /// </summary> - partial void SetNetworkPath(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of NetworkPath to be changed before returning. - /// </summary> - partial void GetNetworkPath(ref string result); - - /// <summary> - /// Max length = 65535 - /// Absolute network path, for example for transcoding sattelites. - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string NetworkPath - { - get - { - string value = _NetworkPath; - GetNetworkPath(ref value); - return (_NetworkPath = value); - } - set - { - string oldValue = _NetworkPath; - SetNetworkPath(oldValue, ref value); - if (oldValue != value) + set { - _NetworkPath = value; + string oldValue = _NetworkPath; + SetNetworkPath(oldValue, ref value); + if (oldValue != value) + { + _NetworkPath = value; + } } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - /// <summary> - /// Required - /// </summary> - public virtual global::Jellyfin.Data.Entities.Library Library { get; set; } - - } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + /// <summary> + /// Required + /// </summary> + [ForeignKey("Library_Id")] + public virtual Library Library { get; set; } + + } } diff --git a/Jellyfin.Data/Entities/MediaFile.cs b/Jellyfin.Data/Entities/MediaFile.cs index 2a47a9632..719539e5c 100644 --- a/Jellyfin.Data/Entities/MediaFile.cs +++ b/Jellyfin.Data/Entities/MediaFile.cs @@ -1,209 +1,200 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class MediaFile - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected MediaFile() - { - MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static MediaFile CreateMediaFileUnsafe() - { - return new MediaFile(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="path">Relative to the LibraryRoot</param> - /// <param name="kind"></param> - /// <param name="_release0"></param> - public MediaFile(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0) - { - if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); - this.Path = path; - - this.Kind = kind; - - if (_release0 == null) throw new ArgumentNullException(nameof(_release0)); - _release0.MediaFiles.Add(this); - - this.MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="path">Relative to the LibraryRoot</param> - /// <param name="kind"></param> - /// <param name="_release0"></param> - public static MediaFile Create(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0) - { - return new MediaFile(path, kind, _release0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class MediaFile + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected MediaFile() + { + MediaFileStreams = new HashSet<MediaFileStream>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static MediaFile CreateMediaFileUnsafe() + { + return new MediaFile(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="path">Relative to the LibraryRoot</param> + /// <param name="kind"></param> + /// <param name="_release0"></param> + public MediaFile(string path, Enums.MediaFileKind kind, Release _release0) + { + if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); + this.Path = path; + + this.Kind = kind; + + if (_release0 == null) throw new ArgumentNullException(nameof(_release0)); + _release0.MediaFiles.Add(this); + + this.MediaFileStreams = new HashSet<MediaFileStream>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="path">Relative to the LibraryRoot</param> + /// <param name="kind"></param> + /// <param name="_release0"></param> + public static MediaFile Create(string path, Enums.MediaFileKind kind, Release _release0) + { + return new MediaFile(path, kind, _release0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for Path + /// </summary> + protected string _Path; + /// <summary> + /// When provided in a partial class, allows value of Path to be changed before setting. + /// </summary> + partial void SetPath(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Path to be changed before returning. + /// </summary> + partial void GetPath(ref string result); + + /// <summary> + /// Required, Max length = 65535 + /// Relative to the LibraryRoot + /// </summary> + [Required] + [MaxLength(65535)] + [StringLength(65535)] + public string Path + { + get + { + string value = _Path; + GetPath(ref value); + return (_Path = value); + } + set { - _Id = value; + string oldValue = _Path; + SetPath(oldValue, ref value); + if (oldValue != value) + { + _Path = value; + } } - } - } - - /// <summary> - /// Backing field for Path - /// </summary> - protected string _Path; - /// <summary> - /// When provided in a partial class, allows value of Path to be changed before setting. - /// </summary> - partial void SetPath(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Path to be changed before returning. - /// </summary> - partial void GetPath(ref string result); - - /// <summary> - /// Required, Max length = 65535 - /// Relative to the LibraryRoot - /// </summary> - [Required] - [MaxLength(65535)] - [StringLength(65535)] - public string Path - { - get - { - string value = _Path; - GetPath(ref value); - return (_Path = value); - } - set - { - string oldValue = _Path; - SetPath(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Kind + /// </summary> + protected Enums.MediaFileKind _Kind; + /// <summary> + /// When provided in a partial class, allows value of Kind to be changed before setting. + /// </summary> + partial void SetKind(Enums.MediaFileKind oldValue, ref Enums.MediaFileKind newValue); + /// <summary> + /// When provided in a partial class, allows value of Kind to be changed before returning. + /// </summary> + partial void GetKind(ref Enums.MediaFileKind result); + + /// <summary> + /// Required + /// </summary> + [Required] + public Enums.MediaFileKind Kind + { + get { - _Path = value; + Enums.MediaFileKind value = _Kind; + GetKind(ref value); + return (_Kind = value); } - } - } - - /// <summary> - /// Backing field for Kind - /// </summary> - protected global::Jellyfin.Data.Enums.MediaFileKind _Kind; - /// <summary> - /// When provided in a partial class, allows value of Kind to be changed before setting. - /// </summary> - partial void SetKind(global::Jellyfin.Data.Enums.MediaFileKind oldValue, ref global::Jellyfin.Data.Enums.MediaFileKind newValue); - /// <summary> - /// When provided in a partial class, allows value of Kind to be changed before returning. - /// </summary> - partial void GetKind(ref global::Jellyfin.Data.Enums.MediaFileKind result); - - /// <summary> - /// Required - /// </summary> - [Required] - public global::Jellyfin.Data.Enums.MediaFileKind Kind - { - get - { - global::Jellyfin.Data.Enums.MediaFileKind value = _Kind; - GetKind(ref value); - return (_Kind = value); - } - set - { - global::Jellyfin.Data.Enums.MediaFileKind oldValue = _Kind; - SetKind(oldValue, ref value); - if (oldValue != value) + set { - _Kind = value; + Enums.MediaFileKind oldValue = _Kind; + SetKind(oldValue, ref value); + if (oldValue != value) + { + _Kind = value; + } } - } - } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.MediaFileStream> MediaFileStreams { get; protected set; } + [ForeignKey("MediaFileStream_MediaFileStreams_Id")] + public virtual ICollection<MediaFileStream> MediaFileStreams { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/MediaFileStream.cs b/Jellyfin.Data/Entities/MediaFileStream.cs index 6593d3cf7..7b3399731 100644 --- a/Jellyfin.Data/Entities/MediaFileStream.cs +++ b/Jellyfin.Data/Entities/MediaFileStream.cs @@ -1,160 +1,149 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class MediaFileStream - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected MediaFileStream() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static MediaFileStream CreateMediaFileStreamUnsafe() - { - return new MediaFileStream(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="streamnumber"></param> - /// <param name="_mediafile0"></param> - public MediaFileStream(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0) - { - this.StreamNumber = streamnumber; - - if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0)); - _mediafile0.MediaFileStreams.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="streamnumber"></param> - /// <param name="_mediafile0"></param> - public static MediaFileStream Create(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0) - { - return new MediaFileStream(streamnumber, _mediafile0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class MediaFileStream + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected MediaFileStream() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static MediaFileStream CreateMediaFileStreamUnsafe() + { + return new MediaFileStream(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="streamnumber"></param> + /// <param name="_mediafile0"></param> + public MediaFileStream(int streamnumber, MediaFile _mediafile0) + { + this.StreamNumber = streamnumber; + + if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0)); + _mediafile0.MediaFileStreams.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="streamnumber"></param> + /// <param name="_mediafile0"></param> + public static MediaFileStream Create(int streamnumber, MediaFile _mediafile0) + { + return new MediaFileStream(streamnumber, _mediafile0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } - - /// <summary> - /// Backing field for StreamNumber - /// </summary> - protected int _StreamNumber; - /// <summary> - /// When provided in a partial class, allows value of StreamNumber to be changed before setting. - /// </summary> - partial void SetStreamNumber(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of StreamNumber to be changed before returning. - /// </summary> - partial void GetStreamNumber(ref int result); - - /// <summary> - /// Required - /// </summary> - [Required] - public int StreamNumber - { - get - { - int value = _StreamNumber; - GetStreamNumber(ref value); - return (_StreamNumber = value); - } - set - { - int oldValue = _StreamNumber; - SetStreamNumber(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for StreamNumber + /// </summary> + protected int _StreamNumber; + /// <summary> + /// When provided in a partial class, allows value of StreamNumber to be changed before setting. + /// </summary> + partial void SetStreamNumber(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of StreamNumber to be changed before returning. + /// </summary> + partial void GetStreamNumber(ref int result); + + /// <summary> + /// Required + /// </summary> + [Required] + public int StreamNumber + { + get { - _StreamNumber = value; + int value = _StreamNumber; + GetStreamNumber(ref value); + return (_StreamNumber = value); } - } - } + set + { + int oldValue = _StreamNumber; + SetStreamNumber(oldValue, ref value); + if (oldValue != value) + { + _StreamNumber = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Metadata.cs b/Jellyfin.Data/Entities/Metadata.cs index 6057017e9..467ee6822 100644 --- a/Jellyfin.Data/Entities/Metadata.cs +++ b/Jellyfin.Data/Entities/Metadata.cs @@ -1,385 +1,380 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public abstract partial class Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to being abstract. - /// </summary> - protected Metadata() - { - PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>(); - Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>(); - Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>(); - Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>(); - Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>(); - - Init(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - this.PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>(); - this.Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>(); - this.Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>(); - this.Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>(); - this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>(); - - Init(); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public abstract partial class Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to being abstract. + /// </summary> + protected Metadata() + { + PersonRoles = new HashSet<PersonRole>(); + Genres = new HashSet<Genre>(); + Artwork = new HashSet<Artwork>(); + Ratings = new HashSet<Rating>(); + Sources = new HashSet<MetadataProviderId>(); + + Init(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + this.PersonRoles = new HashSet<PersonRole>(); + this.Genres = new HashSet<Genre>(); + this.Artwork = new HashSet<Artwork>(); + this.Ratings = new HashSet<Rating>(); + this.Sources = new HashSet<MetadataProviderId>(); + + Init(); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for Title + /// </summary> + protected string _Title; + /// <summary> + /// When provided in a partial class, allows value of Title to be changed before setting. + /// </summary> + partial void SetTitle(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Title to be changed before returning. + /// </summary> + partial void GetTitle(ref string result); + + /// <summary> + /// Required, Max length = 1024 + /// The title or name of the object + /// </summary> + [Required] + [MaxLength(1024)] + [StringLength(1024)] + public string Title + { + get + { + string value = _Title; + GetTitle(ref value); + return (_Title = value); + } + set + { + string oldValue = _Title; + SetTitle(oldValue, ref value); + if (oldValue != value) + { + _Title = value; + } + } + } + + /// <summary> + /// Backing field for OriginalTitle + /// </summary> + protected string _OriginalTitle; + /// <summary> + /// When provided in a partial class, allows value of OriginalTitle to be changed before setting. + /// </summary> + partial void SetOriginalTitle(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of OriginalTitle to be changed before returning. + /// </summary> + partial void GetOriginalTitle(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string OriginalTitle + { + get { - _Id = value; + string value = _OriginalTitle; + GetOriginalTitle(ref value); + return (_OriginalTitle = value); } - } - } - - /// <summary> - /// Backing field for Title - /// </summary> - protected string _Title; - /// <summary> - /// When provided in a partial class, allows value of Title to be changed before setting. - /// </summary> - partial void SetTitle(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Title to be changed before returning. - /// </summary> - partial void GetTitle(ref string result); - - /// <summary> - /// Required, Max length = 1024 - /// The title or name of the object - /// </summary> - [Required] - [MaxLength(1024)] - [StringLength(1024)] - public string Title - { - get - { - string value = _Title; - GetTitle(ref value); - return (_Title = value); - } - set - { - string oldValue = _Title; - SetTitle(oldValue, ref value); - if (oldValue != value) + set { - _Title = value; + string oldValue = _OriginalTitle; + SetOriginalTitle(oldValue, ref value); + if (oldValue != value) + { + _OriginalTitle = value; + } } - } - } - - /// <summary> - /// Backing field for OriginalTitle - /// </summary> - protected string _OriginalTitle; - /// <summary> - /// When provided in a partial class, allows value of OriginalTitle to be changed before setting. - /// </summary> - partial void SetOriginalTitle(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of OriginalTitle to be changed before returning. - /// </summary> - partial void GetOriginalTitle(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string OriginalTitle - { - get - { - string value = _OriginalTitle; - GetOriginalTitle(ref value); - return (_OriginalTitle = value); - } - set - { - string oldValue = _OriginalTitle; - SetOriginalTitle(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for SortTitle + /// </summary> + protected string _SortTitle; + /// <summary> + /// When provided in a partial class, allows value of SortTitle to be changed before setting. + /// </summary> + partial void SetSortTitle(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of SortTitle to be changed before returning. + /// </summary> + partial void GetSortTitle(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string SortTitle + { + get { - _OriginalTitle = value; + string value = _SortTitle; + GetSortTitle(ref value); + return (_SortTitle = value); } - } - } - - /// <summary> - /// Backing field for SortTitle - /// </summary> - protected string _SortTitle; - /// <summary> - /// When provided in a partial class, allows value of SortTitle to be changed before setting. - /// </summary> - partial void SetSortTitle(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of SortTitle to be changed before returning. - /// </summary> - partial void GetSortTitle(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string SortTitle - { - get - { - string value = _SortTitle; - GetSortTitle(ref value); - return (_SortTitle = value); - } - set - { - string oldValue = _SortTitle; - SetSortTitle(oldValue, ref value); - if (oldValue != value) + set { - _SortTitle = value; + string oldValue = _SortTitle; + SetSortTitle(oldValue, ref value); + if (oldValue != value) + { + _SortTitle = value; + } } - } - } - - /// <summary> - /// Backing field for Language - /// </summary> - protected string _Language; - /// <summary> - /// When provided in a partial class, allows value of Language to be changed before setting. - /// </summary> - partial void SetLanguage(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Language to be changed before returning. - /// </summary> - partial void GetLanguage(ref string result); - - /// <summary> - /// Required, Min length = 3, Max length = 3 - /// ISO-639-3 3-character language codes - /// </summary> - [Required] - [MinLength(3)] - [MaxLength(3)] - [StringLength(3)] - public string Language - { - get - { - string value = _Language; - GetLanguage(ref value); - return (_Language = value); - } - set - { - string oldValue = _Language; - SetLanguage(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Language + /// </summary> + protected string _Language; + /// <summary> + /// When provided in a partial class, allows value of Language to be changed before setting. + /// </summary> + partial void SetLanguage(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Language to be changed before returning. + /// </summary> + partial void GetLanguage(ref string result); + + /// <summary> + /// Required, Min length = 3, Max length = 3 + /// ISO-639-3 3-character language codes + /// </summary> + [Required] + [MinLength(3)] + [MaxLength(3)] + [StringLength(3)] + public string Language + { + get { - _Language = value; + string value = _Language; + GetLanguage(ref value); + return (_Language = value); } - } - } - - /// <summary> - /// Backing field for ReleaseDate - /// </summary> - protected DateTimeOffset? _ReleaseDate; - /// <summary> - /// When provided in a partial class, allows value of ReleaseDate to be changed before setting. - /// </summary> - partial void SetReleaseDate(DateTimeOffset? oldValue, ref DateTimeOffset? newValue); - /// <summary> - /// When provided in a partial class, allows value of ReleaseDate to be changed before returning. - /// </summary> - partial void GetReleaseDate(ref DateTimeOffset? result); - - public DateTimeOffset? ReleaseDate - { - get - { - DateTimeOffset? value = _ReleaseDate; - GetReleaseDate(ref value); - return (_ReleaseDate = value); - } - set - { - DateTimeOffset? oldValue = _ReleaseDate; - SetReleaseDate(oldValue, ref value); - if (oldValue != value) + set { - _ReleaseDate = value; + string oldValue = _Language; + SetLanguage(oldValue, ref value); + if (oldValue != value) + { + _Language = value; + } } - } - } - - /// <summary> - /// Backing field for DateAdded - /// </summary> - protected DateTime _DateAdded; - /// <summary> - /// When provided in a partial class, allows value of DateAdded to be changed before setting. - /// </summary> - partial void SetDateAdded(DateTime oldValue, ref DateTime newValue); - /// <summary> - /// When provided in a partial class, allows value of DateAdded to be changed before returning. - /// </summary> - partial void GetDateAdded(ref DateTime result); - - /// <summary> - /// Required - /// </summary> - [Required] - public DateTime DateAdded - { - get - { - DateTime value = _DateAdded; - GetDateAdded(ref value); - return (_DateAdded = value); - } - internal set - { - DateTime oldValue = _DateAdded; - SetDateAdded(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for ReleaseDate + /// </summary> + protected DateTimeOffset? _ReleaseDate; + /// <summary> + /// When provided in a partial class, allows value of ReleaseDate to be changed before setting. + /// </summary> + partial void SetReleaseDate(DateTimeOffset? oldValue, ref DateTimeOffset? newValue); + /// <summary> + /// When provided in a partial class, allows value of ReleaseDate to be changed before returning. + /// </summary> + partial void GetReleaseDate(ref DateTimeOffset? result); + + public DateTimeOffset? ReleaseDate + { + get { - _DateAdded = value; + DateTimeOffset? value = _ReleaseDate; + GetReleaseDate(ref value); + return (_ReleaseDate = value); } - } - } - - /// <summary> - /// Backing field for DateModified - /// </summary> - protected DateTime _DateModified; - /// <summary> - /// When provided in a partial class, allows value of DateModified to be changed before setting. - /// </summary> - partial void SetDateModified(DateTime oldValue, ref DateTime newValue); - /// <summary> - /// When provided in a partial class, allows value of DateModified to be changed before returning. - /// </summary> - partial void GetDateModified(ref DateTime result); - - /// <summary> - /// Required - /// </summary> - [Required] - public DateTime DateModified - { - get - { - DateTime value = _DateModified; - GetDateModified(ref value); - return (_DateModified = value); - } - internal set - { - DateTime oldValue = _DateModified; - SetDateModified(oldValue, ref value); - if (oldValue != value) + set { - _DateModified = value; + DateTimeOffset? oldValue = _ReleaseDate; + SetReleaseDate(oldValue, ref value); + if (oldValue != value) + { + _ReleaseDate = value; + } } - } - } + } + + /// <summary> + /// Backing field for DateAdded + /// </summary> + protected DateTime _DateAdded; + /// <summary> + /// When provided in a partial class, allows value of DateAdded to be changed before setting. + /// </summary> + partial void SetDateAdded(DateTime oldValue, ref DateTime newValue); + /// <summary> + /// When provided in a partial class, allows value of DateAdded to be changed before returning. + /// </summary> + partial void GetDateAdded(ref DateTime result); + + /// <summary> + /// Required + /// </summary> + [Required] + public DateTime DateAdded + { + get + { + DateTime value = _DateAdded; + GetDateAdded(ref value); + return (_DateAdded = value); + } + internal set + { + DateTime oldValue = _DateAdded; + SetDateAdded(oldValue, ref value); + if (oldValue != value) + { + _DateAdded = value; + } + } + } + + /// <summary> + /// Backing field for DateModified + /// </summary> + protected DateTime _DateModified; + /// <summary> + /// When provided in a partial class, allows value of DateModified to be changed before setting. + /// </summary> + partial void SetDateModified(DateTime oldValue, ref DateTime newValue); + /// <summary> + /// When provided in a partial class, allows value of DateModified to be changed before returning. + /// </summary> + partial void GetDateModified(ref DateTime result); + + /// <summary> + /// Required + /// </summary> + [Required] + public DateTime DateModified + { + get + { + DateTime value = _DateModified; + GetDateModified(ref value); + return (_DateModified = value); + } + internal set + { + DateTime oldValue = _DateModified; + SetDateModified(oldValue, ref value); + if (oldValue != value) + { + _DateModified = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.PersonRole> PersonRoles { get; protected set; } + [ForeignKey("PersonRole_PersonRoles_Id")] + public virtual ICollection<PersonRole> PersonRoles { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Genre> Genres { get; protected set; } + [ForeignKey("PersonRole_PersonRoles_Id")] + public virtual ICollection<Genre> Genres { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Artwork> Artwork { get; protected set; } + [ForeignKey("PersonRole_PersonRoles_Id")] + public virtual ICollection<Artwork> Artwork { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Rating> Ratings { get; protected set; } + [ForeignKey("PersonRole_PersonRoles_Id")] + public virtual ICollection<Rating> Ratings { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; } + [ForeignKey("PersonRole_PersonRoles_Id")] + public virtual ICollection<MetadataProviderId> Sources { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/MetadataProvider.cs b/Jellyfin.Data/Entities/MetadataProvider.cs index 3a8f5854e..4e4f107fb 100644 --- a/Jellyfin.Data/Entities/MetadataProvider.cs +++ b/Jellyfin.Data/Entities/MetadataProvider.cs @@ -1,158 +1,147 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class MetadataProvider - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected MetadataProvider() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static MetadataProvider CreateMetadataProviderUnsafe() - { - return new MetadataProvider(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="name"></param> - public MetadataProvider(string name) - { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="name"></param> - public static MetadataProvider Create(string name) - { - return new MetadataProvider(name); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class MetadataProvider + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected MetadataProvider() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static MetadataProvider CreateMetadataProviderUnsafe() + { + return new MetadataProvider(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="name"></param> + public MetadataProvider(string name) + { + if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + this.Name = name; + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="name"></param> + public static MetadataProvider Create(string name) + { + return new MetadataProvider(name); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } - - /// <summary> - /// Backing field for Name - /// </summary> - protected string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); - - /// <summary> - /// Required, Max length = 1024 - /// </summary> - [Required] - [MaxLength(1024)] - [StringLength(1024)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Name + /// </summary> + protected string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); + + /// <summary> + /// Required, Max length = 1024 + /// </summary> + [Required] + [MaxLength(1024)] + [StringLength(1024)] + public string Name + { + get { - _Name = value; + string value = _Name; + GetName(ref value); + return (_Name = value); } - } - } + set + { + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + public void OnSavingChanges() + { + RowVersion++; + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/MetadataProviderId.cs b/Jellyfin.Data/Entities/MetadataProviderId.cs index 87ff19e26..926f223de 100644 --- a/Jellyfin.Data/Entities/MetadataProviderId.cs +++ b/Jellyfin.Data/Entities/MetadataProviderId.cs @@ -1,189 +1,179 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class MetadataProviderId - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected MetadataProviderId() - { - // NOTE: This class has one-to-one associations with MetadataProviderId. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static MetadataProviderId CreateMetadataProviderIdUnsafe() - { - return new MetadataProviderId(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="providerid"></param> - /// <param name="_metadata0"></param> - /// <param name="_person1"></param> - /// <param name="_personrole2"></param> - /// <param name="_ratingsource3"></param> - public MetadataProviderId(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3) - { - // NOTE: This class has one-to-one associations with MetadataProviderId. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid)); - this.ProviderId = providerid; - - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); - _metadata0.Sources.Add(this); - - if (_person1 == null) throw new ArgumentNullException(nameof(_person1)); - _person1.Sources.Add(this); - - if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2)); - _personrole2.Sources.Add(this); - - if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3)); - _ratingsource3.Source = this; - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="providerid"></param> - /// <param name="_metadata0"></param> - /// <param name="_person1"></param> - /// <param name="_personrole2"></param> - /// <param name="_ratingsource3"></param> - public static MetadataProviderId Create(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3) - { - return new MetadataProviderId(providerid, _metadata0, _person1, _personrole2, _ratingsource3); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class MetadataProviderId + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected MetadataProviderId() + { + // NOTE: This class has one-to-one associations with MetadataProviderId. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static MetadataProviderId CreateMetadataProviderIdUnsafe() + { + return new MetadataProviderId(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="providerid"></param> + /// <param name="_metadata0"></param> + /// <param name="_person1"></param> + /// <param name="_personrole2"></param> + /// <param name="_ratingsource3"></param> + public MetadataProviderId(string providerid, Metadata _metadata0, Person _person1, PersonRole _personrole2, RatingSource _ratingsource3) + { + // NOTE: This class has one-to-one associations with MetadataProviderId. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid)); + this.ProviderId = providerid; + + if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + _metadata0.Sources.Add(this); + + if (_person1 == null) throw new ArgumentNullException(nameof(_person1)); + _person1.Sources.Add(this); + + if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2)); + _personrole2.Sources.Add(this); + + if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3)); + _ratingsource3.Source = this; + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="providerid"></param> + /// <param name="_metadata0"></param> + /// <param name="_person1"></param> + /// <param name="_personrole2"></param> + /// <param name="_ratingsource3"></param> + public static MetadataProviderId Create(string providerid, Metadata _metadata0, Person _person1, PersonRole _personrole2, RatingSource _ratingsource3) + { + return new MetadataProviderId(providerid, _metadata0, _person1, _personrole2, _ratingsource3); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for ProviderId + /// </summary> + protected string _ProviderId; + /// <summary> + /// When provided in a partial class, allows value of ProviderId to be changed before setting. + /// </summary> + partial void SetProviderId(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of ProviderId to be changed before returning. + /// </summary> + partial void GetProviderId(ref string result); + + /// <summary> + /// Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string ProviderId + { + get { - _Id = value; + string value = _ProviderId; + GetProviderId(ref value); + return (_ProviderId = value); } - } - } - - /// <summary> - /// Backing field for ProviderId - /// </summary> - protected string _ProviderId; - /// <summary> - /// When provided in a partial class, allows value of ProviderId to be changed before setting. - /// </summary> - partial void SetProviderId(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of ProviderId to be changed before returning. - /// </summary> - partial void GetProviderId(ref string result); - - /// <summary> - /// Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string ProviderId - { - get - { - string value = _ProviderId; - GetProviderId(ref value); - return (_ProviderId = value); - } - set - { - string oldValue = _ProviderId; - SetProviderId(oldValue, ref value); - if (oldValue != value) + set { - _ProviderId = value; + string oldValue = _ProviderId; + SetProviderId(oldValue, ref value); + if (oldValue != value) + { + _ProviderId = value; + } } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - /// <summary> - /// Required - /// </summary> - public virtual global::Jellyfin.Data.Entities.MetadataProvider MetadataProvider { get; set; } - - } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + /// <summary> + /// Required + /// </summary> + [ForeignKey("MetadataProvider_Id")] + public virtual MetadataProvider MetadataProvider { get; set; } + + } } diff --git a/Jellyfin.Data/Entities/Movie.cs b/Jellyfin.Data/Entities/Movie.cs index dfcc05a94..b359b42fc 100644 --- a/Jellyfin.Data/Entities/Movie.cs +++ b/Jellyfin.Data/Entities/Movie.cs @@ -1,84 +1,69 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Movie: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); + public partial class Movie : LibraryItem + { + partial void Init(); - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Movie(): base() - { - Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); - MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>(); + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Movie() + { + Releases = new HashSet<Release>(); + MovieMetadata = new HashSet<MovieMetadata>(); - Init(); - } + Init(); + } - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Movie CreateMovieUnsafe() - { - return new Movie(); - } + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Movie CreateMovieUnsafe() + { + return new Movie(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public Movie(Guid urlid, DateTime dateadded) - { - this.UrlId = urlid; + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public Movie(Guid urlid, DateTime dateadded) + { + this.UrlId = urlid; - this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); - this.MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>(); + this.Releases = new HashSet<Release>(); + this.MovieMetadata = new HashSet<MovieMetadata>(); - Init(); - } + Init(); + } - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public static Movie Create(Guid urlid, DateTime dateadded) - { - return new Movie(urlid, dateadded); - } + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public static Movie Create(Guid urlid, DateTime dateadded) + { + return new Movie(urlid, dateadded); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; } + [ForeignKey("Release_Releases_Id")] + public virtual ICollection<Release> Releases { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.MovieMetadata> MovieMetadata { get; protected set; } + [ForeignKey("MovieMetadata_MovieMetadata_Id")] + public virtual ICollection<MovieMetadata> MovieMetadata { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/MovieMetadata.cs b/Jellyfin.Data/Entities/MovieMetadata.cs index bd847da8f..319ae94e5 100644 --- a/Jellyfin.Data/Entities/MovieMetadata.cs +++ b/Jellyfin.Data/Entities/MovieMetadata.cs @@ -1,239 +1,223 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class MovieMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected MovieMetadata(): base() - { - Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static MovieMetadata CreateMovieMetadataUnsafe() - { - return new MovieMetadata(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_movie0"></param> - public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0)); - _movie0.MovieMetadata.Add(this); - - this.Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_movie0"></param> - public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0) - { - return new MovieMetadata(title, language, dateadded, datemodified, _movie0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Outline - /// </summary> - protected string _Outline; - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before setting. - /// </summary> - partial void SetOutline(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before returning. - /// </summary> - partial void GetOutline(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Outline - { - get - { - string value = _Outline; - GetOutline(ref value); - return (_Outline = value); - } - set - { - string oldValue = _Outline; - SetOutline(oldValue, ref value); - if (oldValue != value) + public partial class MovieMetadata : Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected MovieMetadata() + { + Studios = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static MovieMetadata CreateMovieMetadataUnsafe() + { + return new MovieMetadata(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_movie0"></param> + public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0)); + _movie0.MovieMetadata.Add(this); + + this.Studios = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_movie0"></param> + public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0) + { + return new MovieMetadata(title, language, dateadded, datemodified, _movie0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Outline + /// </summary> + protected string _Outline; + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before setting. + /// </summary> + partial void SetOutline(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before returning. + /// </summary> + partial void GetOutline(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Outline + { + get { - _Outline = value; + string value = _Outline; + GetOutline(ref value); + return (_Outline = value); } - } - } - - /// <summary> - /// Backing field for Plot - /// </summary> - protected string _Plot; - /// <summary> - /// When provided in a partial class, allows value of Plot to be changed before setting. - /// </summary> - partial void SetPlot(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Plot to be changed before returning. - /// </summary> - partial void GetPlot(ref string result); - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string Plot - { - get - { - string value = _Plot; - GetPlot(ref value); - return (_Plot = value); - } - set - { - string oldValue = _Plot; - SetPlot(oldValue, ref value); - if (oldValue != value) + set { - _Plot = value; + string oldValue = _Outline; + SetOutline(oldValue, ref value); + if (oldValue != value) + { + _Outline = value; + } } - } - } - - /// <summary> - /// Backing field for Tagline - /// </summary> - protected string _Tagline; - /// <summary> - /// When provided in a partial class, allows value of Tagline to be changed before setting. - /// </summary> - partial void SetTagline(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Tagline to be changed before returning. - /// </summary> - partial void GetTagline(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Tagline - { - get - { - string value = _Tagline; - GetTagline(ref value); - return (_Tagline = value); - } - set - { - string oldValue = _Tagline; - SetTagline(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Plot + /// </summary> + protected string _Plot; + /// <summary> + /// When provided in a partial class, allows value of Plot to be changed before setting. + /// </summary> + partial void SetPlot(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Plot to be changed before returning. + /// </summary> + partial void GetPlot(ref string result); + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string Plot + { + get { - _Tagline = value; + string value = _Plot; + GetPlot(ref value); + return (_Plot = value); } - } - } - - /// <summary> - /// Backing field for Country - /// </summary> - protected string _Country; - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before setting. - /// </summary> - partial void SetCountry(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before returning. - /// </summary> - partial void GetCountry(ref string result); - - /// <summary> - /// Max length = 2 - /// </summary> - [MaxLength(2)] - [StringLength(2)] - public string Country - { - get - { - string value = _Country; - GetCountry(ref value); - return (_Country = value); - } - set - { - string oldValue = _Country; - SetCountry(oldValue, ref value); - if (oldValue != value) + set { - _Country = value; + string oldValue = _Plot; + SetPlot(oldValue, ref value); + if (oldValue != value) + { + _Plot = value; + } } - } - } - - /************************************************************************* - * Navigation properties - *************************************************************************/ + } + + /// <summary> + /// Backing field for Tagline + /// </summary> + protected string _Tagline; + /// <summary> + /// When provided in a partial class, allows value of Tagline to be changed before setting. + /// </summary> + partial void SetTagline(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Tagline to be changed before returning. + /// </summary> + partial void GetTagline(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Tagline + { + get + { + string value = _Tagline; + GetTagline(ref value); + return (_Tagline = value); + } + set + { + string oldValue = _Tagline; + SetTagline(oldValue, ref value); + if (oldValue != value) + { + _Tagline = value; + } + } + } + + /// <summary> + /// Backing field for Country + /// </summary> + protected string _Country; + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before setting. + /// </summary> + partial void SetCountry(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before returning. + /// </summary> + partial void GetCountry(ref string result); + + /// <summary> + /// Max length = 2 + /// </summary> + [MaxLength(2)] + [StringLength(2)] + public string Country + { + get + { + string value = _Country; + GetCountry(ref value); + return (_Country = value); + } + set + { + string oldValue = _Country; + SetCountry(oldValue, ref value); + if (oldValue != value) + { + _Country = value; + } + } + } - public virtual ICollection<global::Jellyfin.Data.Entities.Company> Studios { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("Company_Studios_Id")] + public virtual ICollection<Company> Studios { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/MusicAlbum.cs b/Jellyfin.Data/Entities/MusicAlbum.cs index 417f2595b..00cb8fe00 100644 --- a/Jellyfin.Data/Entities/MusicAlbum.cs +++ b/Jellyfin.Data/Entities/MusicAlbum.cs @@ -1,84 +1,68 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class MusicAlbum: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected MusicAlbum(): base() - { - MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>(); - Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>(); + public partial class MusicAlbum : LibraryItem + { + partial void Init(); - Init(); - } + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected MusicAlbum() + { + MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>(); + Tracks = new HashSet<Track>(); - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static MusicAlbum CreateMusicAlbumUnsafe() - { - return new MusicAlbum(); - } + Init(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public MusicAlbum(Guid urlid, DateTime dateadded) - { - this.UrlId = urlid; + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static MusicAlbum CreateMusicAlbumUnsafe() + { + return new MusicAlbum(); + } - this.MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>(); - this.Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>(); + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public MusicAlbum(Guid urlid, DateTime dateadded) + { + this.UrlId = urlid; - Init(); - } + this.MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>(); + this.Tracks = new HashSet<Track>(); - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public static MusicAlbum Create(Guid urlid, DateTime dateadded) - { - return new MusicAlbum(urlid, dateadded); - } + Init(); + } - /************************************************************************* - * Properties - *************************************************************************/ + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public static MusicAlbum Create(Guid urlid, DateTime dateadded) + { + return new MusicAlbum(urlid, dateadded); + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id")] + public virtual ICollection<MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Track> Tracks { get; protected set; } + [ForeignKey("Track_Tracks_Id")] + public virtual ICollection<Track> Tracks { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs index cd72ecba5..b52ca6564 100644 --- a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs +++ b/Jellyfin.Data/Entities/MusicAlbumMetadata.cs @@ -1,202 +1,187 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class MusicAlbumMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected MusicAlbumMetadata(): base() - { - Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static MusicAlbumMetadata CreateMusicAlbumMetadataUnsafe() - { - return new MusicAlbumMetadata(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_musicalbum0"></param> - public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0)); - _musicalbum0.MusicAlbumMetadata.Add(this); - - this.Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_musicalbum0"></param> - public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0) - { - return new MusicAlbumMetadata(title, language, dateadded, datemodified, _musicalbum0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Barcode - /// </summary> - protected string _Barcode; - /// <summary> - /// When provided in a partial class, allows value of Barcode to be changed before setting. - /// </summary> - partial void SetBarcode(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Barcode to be changed before returning. - /// </summary> - partial void GetBarcode(ref string result); - - /// <summary> - /// Max length = 255 - /// </summary> - [MaxLength(255)] - [StringLength(255)] - public string Barcode - { - get - { - string value = _Barcode; - GetBarcode(ref value); - return (_Barcode = value); - } - set - { - string oldValue = _Barcode; - SetBarcode(oldValue, ref value); - if (oldValue != value) + public partial class MusicAlbumMetadata : Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected MusicAlbumMetadata() + { + Labels = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static MusicAlbumMetadata CreateMusicAlbumMetadataUnsafe() + { + return new MusicAlbumMetadata(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_musicalbum0"></param> + public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0)); + _musicalbum0.MusicAlbumMetadata.Add(this); + + this.Labels = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_musicalbum0"></param> + public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0) + { + return new MusicAlbumMetadata(title, language, dateadded, datemodified, _musicalbum0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Barcode + /// </summary> + protected string _Barcode; + /// <summary> + /// When provided in a partial class, allows value of Barcode to be changed before setting. + /// </summary> + partial void SetBarcode(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Barcode to be changed before returning. + /// </summary> + partial void GetBarcode(ref string result); + + /// <summary> + /// Max length = 255 + /// </summary> + [MaxLength(255)] + [StringLength(255)] + public string Barcode + { + get + { + string value = _Barcode; + GetBarcode(ref value); + return (_Barcode = value); + } + set + { + string oldValue = _Barcode; + SetBarcode(oldValue, ref value); + if (oldValue != value) + { + _Barcode = value; + } + } + } + + /// <summary> + /// Backing field for LabelNumber + /// </summary> + protected string _LabelNumber; + /// <summary> + /// When provided in a partial class, allows value of LabelNumber to be changed before setting. + /// </summary> + partial void SetLabelNumber(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of LabelNumber to be changed before returning. + /// </summary> + partial void GetLabelNumber(ref string result); + + /// <summary> + /// Max length = 255 + /// </summary> + [MaxLength(255)] + [StringLength(255)] + public string LabelNumber + { + get + { + string value = _LabelNumber; + GetLabelNumber(ref value); + return (_LabelNumber = value); + } + set { - _Barcode = value; + string oldValue = _LabelNumber; + SetLabelNumber(oldValue, ref value); + if (oldValue != value) + { + _LabelNumber = value; + } } - } - } - - /// <summary> - /// Backing field for LabelNumber - /// </summary> - protected string _LabelNumber; - /// <summary> - /// When provided in a partial class, allows value of LabelNumber to be changed before setting. - /// </summary> - partial void SetLabelNumber(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of LabelNumber to be changed before returning. - /// </summary> - partial void GetLabelNumber(ref string result); - - /// <summary> - /// Max length = 255 - /// </summary> - [MaxLength(255)] - [StringLength(255)] - public string LabelNumber - { - get - { - string value = _LabelNumber; - GetLabelNumber(ref value); - return (_LabelNumber = value); - } - set - { - string oldValue = _LabelNumber; - SetLabelNumber(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Country + /// </summary> + protected string _Country; + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before setting. + /// </summary> + partial void SetCountry(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before returning. + /// </summary> + partial void GetCountry(ref string result); + + /// <summary> + /// Max length = 2 + /// </summary> + [MaxLength(2)] + [StringLength(2)] + public string Country + { + get { - _LabelNumber = value; + string value = _Country; + GetCountry(ref value); + return (_Country = value); } - } - } - - /// <summary> - /// Backing field for Country - /// </summary> - protected string _Country; - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before setting. - /// </summary> - partial void SetCountry(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before returning. - /// </summary> - partial void GetCountry(ref string result); - - /// <summary> - /// Max length = 2 - /// </summary> - [MaxLength(2)] - [StringLength(2)] - public string Country - { - get - { - string value = _Country; - GetCountry(ref value); - return (_Country = value); - } - set - { - string oldValue = _Country; - SetCountry(oldValue, ref value); - if (oldValue != value) + set { - _Country = value; + string oldValue = _Country; + SetCountry(oldValue, ref value); + if (oldValue != value) + { + _Country = value; + } } - } - } + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.Company> Labels { get; protected set; } + [ForeignKey("Company_Labels_Id")] + public virtual ICollection<Company> Labels { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/Permission.cs b/Jellyfin.Data/Entities/Permission.cs index a717fc83f..0b5b52cbd 100644 --- a/Jellyfin.Data/Entities/Permission.cs +++ b/Jellyfin.Data/Entities/Permission.cs @@ -1,152 +1,144 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Permission - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Permission() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Permission CreatePermissionUnsafe() - { - return new Permission(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="kind"></param> - /// <param name="value"></param> - /// <param name="_user0"></param> - /// <param name="_group1"></param> - public Permission(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1) - { - this.Kind = kind; - - this.Value = value; - - if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); - _user0.Permissions.Add(this); - - if (_group1 == null) throw new ArgumentNullException(nameof(_group1)); - _group1.GroupPermissions.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="kind"></param> - /// <param name="value"></param> - /// <param name="_user0"></param> - /// <param name="_group1"></param> - public static Permission Create(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1) - { - return new Permission(kind, value, _user0, _group1); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id { get; protected set; } - - /// <summary> - /// Backing field for Kind - /// </summary> - protected global::Jellyfin.Data.Enums.PermissionKind _Kind; - /// <summary> - /// When provided in a partial class, allows value of Kind to be changed before setting. - /// </summary> - partial void SetKind(global::Jellyfin.Data.Enums.PermissionKind oldValue, ref global::Jellyfin.Data.Enums.PermissionKind newValue); - /// <summary> - /// When provided in a partial class, allows value of Kind to be changed before returning. - /// </summary> - partial void GetKind(ref global::Jellyfin.Data.Enums.PermissionKind result); - - /// <summary> - /// Required - /// </summary> - [Required] - public global::Jellyfin.Data.Enums.PermissionKind Kind - { - get - { - global::Jellyfin.Data.Enums.PermissionKind value = _Kind; - GetKind(ref value); - return (_Kind = value); - } - set - { - global::Jellyfin.Data.Enums.PermissionKind oldValue = _Kind; - SetKind(oldValue, ref value); - if (oldValue != value) + public partial class Permission + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Permission() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Permission CreatePermissionUnsafe() + { + return new Permission(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="kind"></param> + /// <param name="value"></param> + /// <param name="_user0"></param> + /// <param name="_group1"></param> + public Permission(Enums.PermissionKind kind, bool value, User _user0, Group _group1) + { + this.Kind = kind; + + this.Value = value; + + if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); + _user0.Permissions.Add(this); + + if (_group1 == null) throw new ArgumentNullException(nameof(_group1)); + _group1.GroupPermissions.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="kind"></param> + /// <param name="value"></param> + /// <param name="_user0"></param> + /// <param name="_group1"></param> + public static Permission Create(Enums.PermissionKind kind, bool value, User _user0, Group _group1) + { + return new Permission(kind, value, _user0, _group1); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; protected set; } + + /// <summary> + /// Backing field for Kind + /// </summary> + protected Enums.PermissionKind _Kind; + /// <summary> + /// When provided in a partial class, allows value of Kind to be changed before setting. + /// </summary> + partial void SetKind(Enums.PermissionKind oldValue, ref Enums.PermissionKind newValue); + /// <summary> + /// When provided in a partial class, allows value of Kind to be changed before returning. + /// </summary> + partial void GetKind(ref Enums.PermissionKind result); + + /// <summary> + /// Required + /// </summary> + [Required] + public Enums.PermissionKind Kind + { + get { - _Kind = value; - OnPropertyChanged(); + Enums.PermissionKind value = _Kind; + GetKind(ref value); + return (_Kind = value); } - } - } - - /// <summary> - /// Required - /// </summary> - [Required] - public bool Value { get; set; } - - /// <summary> - /// Concurrency token - /// </summary> - [Timestamp] - public Byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - public virtual event PropertyChangedEventHandler PropertyChanged; - - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - } + set + { + Enums.PermissionKind oldValue = _Kind; + SetKind(oldValue, ref value); + if (oldValue != value) + { + _Kind = value; + OnPropertyChanged(); + } + } + } + + /// <summary> + /// Required + /// </summary> + [Required] + public bool Value { get; set; } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + public virtual event PropertyChangedEventHandler PropertyChanged; + + protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + } } diff --git a/Jellyfin.Data/Entities/PermissionKind.cs b/Jellyfin.Data/Entities/PermissionKind.cs deleted file mode 100644 index 971298674..000000000 --- a/Jellyfin.Data/Entities/PermissionKind.cs +++ /dev/null @@ -1,40 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; - -namespace Jellyfin.Data.Enums -{ - public enum PermissionKind : Int32 - { - IsAdministrator, - IsHidden, - IsDisabled, - BlockUnrateditems, - EnbleSharedDeviceControl, - EnableRemoteAccess, - EnableLiveTvManagement, - EnableLiveTvAccess, - EnableMediaPlayback, - EnableAudioPlaybackTranscoding, - EnableVideoPlaybackTranscoding, - EnableContentDeletion, - EnableContentDownloading, - EnableSyncTranscoding, - EnableMediaConversion, - EnableAllDevices, - EnableAllChannels, - EnableAllFolders, - EnablePublicSharing, - AccessSchedules - } -} diff --git a/Jellyfin.Data/Entities/Person.cs b/Jellyfin.Data/Entities/Person.cs index 3437b9581..d893b7e39 100644 --- a/Jellyfin.Data/Entities/Person.cs +++ b/Jellyfin.Data/Entities/Person.cs @@ -1,312 +1,302 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Person - { - partial void Init(); + public partial class Person + { + partial void Init(); - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Person() - { - Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>(); + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Person() + { + Sources = new HashSet<MetadataProviderId>(); - Init(); - } + Init(); + } - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Person CreatePersonUnsafe() - { - return new Person(); - } + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Person CreatePersonUnsafe() + { + return new Person(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid"></param> - /// <param name="name"></param> - public Person(Guid urlid, string name, DateTime dateadded, DateTime datemodified) - { - this.UrlId = urlid; + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid"></param> + /// <param name="name"></param> + public Person(Guid urlid, string name, DateTime dateadded, DateTime datemodified) + { + this.UrlId = urlid; - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; + if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + this.Name = name; - this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>(); + this.Sources = new HashSet<MetadataProviderId>(); - Init(); - } + Init(); + } - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid"></param> - /// <param name="name"></param> - public static Person Create(Guid urlid, string name, DateTime dateadded, DateTime datemodified) - { - return new Person(urlid, name, dateadded, datemodified); - } + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid"></param> + /// <param name="name"></param> + public static Person Create(Guid urlid, string name, DateTime dateadded, DateTime datemodified) + { + return new Person(urlid, name, dateadded, datemodified); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set { - _Id = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } + } - /// <summary> - /// Backing field for UrlId - /// </summary> - protected Guid _UrlId; - /// <summary> - /// When provided in a partial class, allows value of UrlId to be changed before setting. - /// </summary> - partial void SetUrlId(Guid oldValue, ref Guid newValue); - /// <summary> - /// When provided in a partial class, allows value of UrlId to be changed before returning. - /// </summary> - partial void GetUrlId(ref Guid result); + /// <summary> + /// Backing field for UrlId + /// </summary> + protected Guid _UrlId; + /// <summary> + /// When provided in a partial class, allows value of UrlId to be changed before setting. + /// </summary> + partial void SetUrlId(Guid oldValue, ref Guid newValue); + /// <summary> + /// When provided in a partial class, allows value of UrlId to be changed before returning. + /// </summary> + partial void GetUrlId(ref Guid result); - /// <summary> - /// Required - /// </summary> - [Required] - public Guid UrlId - { - get - { - Guid value = _UrlId; - GetUrlId(ref value); - return (_UrlId = value); - } - set - { - Guid oldValue = _UrlId; - SetUrlId(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Required + /// </summary> + [Required] + public Guid UrlId + { + get { - _UrlId = value; + Guid value = _UrlId; + GetUrlId(ref value); + return (_UrlId = value); } - } - } + set + { + Guid oldValue = _UrlId; + SetUrlId(oldValue, ref value); + if (oldValue != value) + { + _UrlId = value; + } + } + } - /// <summary> - /// Backing field for Name - /// </summary> - protected string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); + /// <summary> + /// Backing field for Name + /// </summary> + protected string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); - /// <summary> - /// Required, Max length = 1024 - /// </summary> - [Required] - [MaxLength(1024)] - [StringLength(1024)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Required, Max length = 1024 + /// </summary> + [Required] + [MaxLength(1024)] + [StringLength(1024)] + public string Name + { + get + { + string value = _Name; + GetName(ref value); + return (_Name = value); + } + set { - _Name = value; + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } } - } - } + } - /// <summary> - /// Backing field for SourceId - /// </summary> - protected string _SourceId; - /// <summary> - /// When provided in a partial class, allows value of SourceId to be changed before setting. - /// </summary> - partial void SetSourceId(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of SourceId to be changed before returning. - /// </summary> - partial void GetSourceId(ref string result); + /// <summary> + /// Backing field for SourceId + /// </summary> + protected string _SourceId; + /// <summary> + /// When provided in a partial class, allows value of SourceId to be changed before setting. + /// </summary> + partial void SetSourceId(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of SourceId to be changed before returning. + /// </summary> + partial void GetSourceId(ref string result); - /// <summary> - /// Max length = 255 - /// </summary> - [MaxLength(255)] - [StringLength(255)] - public string SourceId - { - get - { - string value = _SourceId; - GetSourceId(ref value); - return (_SourceId = value); - } - set - { - string oldValue = _SourceId; - SetSourceId(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Max length = 255 + /// </summary> + [MaxLength(255)] + [StringLength(255)] + public string SourceId + { + get { - _SourceId = value; + string value = _SourceId; + GetSourceId(ref value); + return (_SourceId = value); } - } - } + set + { + string oldValue = _SourceId; + SetSourceId(oldValue, ref value); + if (oldValue != value) + { + _SourceId = value; + } + } + } - /// <summary> - /// Backing field for DateAdded - /// </summary> - protected DateTime _DateAdded; - /// <summary> - /// When provided in a partial class, allows value of DateAdded to be changed before setting. - /// </summary> - partial void SetDateAdded(DateTime oldValue, ref DateTime newValue); - /// <summary> - /// When provided in a partial class, allows value of DateAdded to be changed before returning. - /// </summary> - partial void GetDateAdded(ref DateTime result); + /// <summary> + /// Backing field for DateAdded + /// </summary> + protected DateTime _DateAdded; + /// <summary> + /// When provided in a partial class, allows value of DateAdded to be changed before setting. + /// </summary> + partial void SetDateAdded(DateTime oldValue, ref DateTime newValue); + /// <summary> + /// When provided in a partial class, allows value of DateAdded to be changed before returning. + /// </summary> + partial void GetDateAdded(ref DateTime result); - /// <summary> - /// Required - /// </summary> - [Required] - public DateTime DateAdded - { - get - { - DateTime value = _DateAdded; - GetDateAdded(ref value); - return (_DateAdded = value); - } - internal set - { - DateTime oldValue = _DateAdded; - SetDateAdded(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Required + /// </summary> + [Required] + public DateTime DateAdded + { + get + { + DateTime value = _DateAdded; + GetDateAdded(ref value); + return (_DateAdded = value); + } + internal set { - _DateAdded = value; + DateTime oldValue = _DateAdded; + SetDateAdded(oldValue, ref value); + if (oldValue != value) + { + _DateAdded = value; + } } - } - } + } - /// <summary> - /// Backing field for DateModified - /// </summary> - protected DateTime _DateModified; - /// <summary> - /// When provided in a partial class, allows value of DateModified to be changed before setting. - /// </summary> - partial void SetDateModified(DateTime oldValue, ref DateTime newValue); - /// <summary> - /// When provided in a partial class, allows value of DateModified to be changed before returning. - /// </summary> - partial void GetDateModified(ref DateTime result); + /// <summary> + /// Backing field for DateModified + /// </summary> + protected DateTime _DateModified; + /// <summary> + /// When provided in a partial class, allows value of DateModified to be changed before setting. + /// </summary> + partial void SetDateModified(DateTime oldValue, ref DateTime newValue); + /// <summary> + /// When provided in a partial class, allows value of DateModified to be changed before returning. + /// </summary> + partial void GetDateModified(ref DateTime result); - /// <summary> - /// Required - /// </summary> - [Required] - public DateTime DateModified - { - get - { - DateTime value = _DateModified; - GetDateModified(ref value); - return (_DateModified = value); - } - internal set - { - DateTime oldValue = _DateModified; - SetDateModified(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// Required + /// </summary> + [Required] + public DateTime DateModified + { + get + { + DateTime value = _DateModified; + GetDateModified(ref value); + return (_DateModified = value); + } + internal set { - _DateModified = value; + DateTime oldValue = _DateModified; + SetDateModified(oldValue, ref value); + if (oldValue != value) + { + _DateModified = value; + } } - } - } + } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } - /************************************************************************* - * Navigation properties - *************************************************************************/ + public void OnSavingChanges() + { + RowVersion++; + } - public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("MetadataProviderId_Sources_Id")] + public virtual ICollection<MetadataProviderId> Sources { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/PersonRole.cs b/Jellyfin.Data/Entities/PersonRole.cs index d8e2dbc11..9bd12c7fb 100644 --- a/Jellyfin.Data/Entities/PersonRole.cs +++ b/Jellyfin.Data/Entities/PersonRole.cs @@ -1,215 +1,209 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class PersonRole - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected PersonRole() - { - // NOTE: This class has one-to-one associations with PersonRole. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static PersonRole CreatePersonRoleUnsafe() - { - return new PersonRole(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="type"></param> - /// <param name="_metadata0"></param> - public PersonRole(global::Jellyfin.Data.Enums.PersonRoleType type, global::Jellyfin.Data.Entities.Metadata _metadata0) - { - // NOTE: This class has one-to-one associations with PersonRole. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - this.Type = type; - - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); - _metadata0.PersonRoles.Add(this); - - this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="type"></param> - /// <param name="_metadata0"></param> - public static PersonRole Create(global::Jellyfin.Data.Enums.PersonRoleType type, global::Jellyfin.Data.Entities.Metadata _metadata0) - { - return new PersonRole(type, _metadata0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class PersonRole + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected PersonRole() + { + // NOTE: This class has one-to-one associations with PersonRole. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + Sources = new HashSet<MetadataProviderId>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static PersonRole CreatePersonRoleUnsafe() + { + return new PersonRole(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="type"></param> + /// <param name="_metadata0"></param> + public PersonRole(Enums.PersonRoleType type, Metadata _metadata0) + { + // NOTE: This class has one-to-one associations with PersonRole. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + this.Type = type; + + if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + _metadata0.PersonRoles.Add(this); + + this.Sources = new HashSet<MetadataProviderId>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="type"></param> + /// <param name="_metadata0"></param> + public static PersonRole Create(Enums.PersonRoleType type, Metadata _metadata0) + { + return new PersonRole(type, _metadata0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for Role + /// </summary> + protected string _Role; + /// <summary> + /// When provided in a partial class, allows value of Role to be changed before setting. + /// </summary> + partial void SetRole(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Role to be changed before returning. + /// </summary> + partial void GetRole(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Role + { + get { - _Id = value; + string value = _Role; + GetRole(ref value); + return (_Role = value); } - } - } - - /// <summary> - /// Backing field for Role - /// </summary> - protected string _Role; - /// <summary> - /// When provided in a partial class, allows value of Role to be changed before setting. - /// </summary> - partial void SetRole(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Role to be changed before returning. - /// </summary> - partial void GetRole(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Role - { - get - { - string value = _Role; - GetRole(ref value); - return (_Role = value); - } - set - { - string oldValue = _Role; - SetRole(oldValue, ref value); - if (oldValue != value) + set { - _Role = value; + string oldValue = _Role; + SetRole(oldValue, ref value); + if (oldValue != value) + { + _Role = value; + } } - } - } - - /// <summary> - /// Backing field for Type - /// </summary> - protected global::Jellyfin.Data.Enums.PersonRoleType _Type; - /// <summary> - /// When provided in a partial class, allows value of Type to be changed before setting. - /// </summary> - partial void SetType(global::Jellyfin.Data.Enums.PersonRoleType oldValue, ref global::Jellyfin.Data.Enums.PersonRoleType newValue); - /// <summary> - /// When provided in a partial class, allows value of Type to be changed before returning. - /// </summary> - partial void GetType(ref global::Jellyfin.Data.Enums.PersonRoleType result); - - /// <summary> - /// Required - /// </summary> - [Required] - public global::Jellyfin.Data.Enums.PersonRoleType Type - { - get - { - global::Jellyfin.Data.Enums.PersonRoleType value = _Type; - GetType(ref value); - return (_Type = value); - } - set - { - global::Jellyfin.Data.Enums.PersonRoleType oldValue = _Type; - SetType(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Type + /// </summary> + protected Enums.PersonRoleType _Type; + /// <summary> + /// When provided in a partial class, allows value of Type to be changed before setting. + /// </summary> + partial void SetType(Enums.PersonRoleType oldValue, ref Enums.PersonRoleType newValue); + /// <summary> + /// When provided in a partial class, allows value of Type to be changed before returning. + /// </summary> + partial void GetType(ref Enums.PersonRoleType result); + + /// <summary> + /// Required + /// </summary> + [Required] + public Enums.PersonRoleType Type + { + get { - _Type = value; + Enums.PersonRoleType value = _Type; + GetType(ref value); + return (_Type = value); } - } - } + set + { + Enums.PersonRoleType oldValue = _Type; + SetType(oldValue, ref value); + if (oldValue != value) + { + _Type = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ - /************************************************************************* - * Navigation properties - *************************************************************************/ + /// <summary> + /// Required + /// </summary> + [ForeignKey("Person_Id")] - /// <summary> - /// Required - /// </summary> - public virtual global::Jellyfin.Data.Entities.Person Person { get; set; } + public virtual Person Person { get; set; } - public virtual global::Jellyfin.Data.Entities.Artwork Artwork { get; set; } + [ForeignKey("Artwork_Artwork_Id")] + public virtual Artwork Artwork { get; set; } - public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; } + [ForeignKey("MetadataProviderId_Sources_Id")] + public virtual ICollection<MetadataProviderId> Sources { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/Photo.cs b/Jellyfin.Data/Entities/Photo.cs index 16c97fef5..7abe62891 100644 --- a/Jellyfin.Data/Entities/Photo.cs +++ b/Jellyfin.Data/Entities/Photo.cs @@ -1,84 +1,68 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Photo: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Photo(): base() - { - PhotoMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PhotoMetadata>(); - Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); + public partial class Photo : LibraryItem + { + partial void Init(); - Init(); - } + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Photo() + { + PhotoMetadata = new HashSet<PhotoMetadata>(); + Releases = new HashSet<Release>(); - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Photo CreatePhotoUnsafe() - { - return new Photo(); - } + Init(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public Photo(Guid urlid, DateTime dateadded) - { - this.UrlId = urlid; + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Photo CreatePhotoUnsafe() + { + return new Photo(); + } - this.PhotoMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PhotoMetadata>(); - this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public Photo(Guid urlid, DateTime dateadded) + { + this.UrlId = urlid; - Init(); - } + this.PhotoMetadata = new HashSet<PhotoMetadata>(); + this.Releases = new HashSet<Release>(); - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public static Photo Create(Guid urlid, DateTime dateadded) - { - return new Photo(urlid, dateadded); - } + Init(); + } - /************************************************************************* - * Properties - *************************************************************************/ + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public static Photo Create(Guid urlid, DateTime dateadded) + { + return new Photo(urlid, dateadded); + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.PhotoMetadata> PhotoMetadata { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("PhotoMetadata_PhotoMetadata_Id")] + public virtual ICollection<PhotoMetadata> PhotoMetadata { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; } + [ForeignKey("Release_Releases_Id")] + public virtual ICollection<Release> Releases { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/PhotoMetadata.cs b/Jellyfin.Data/Entities/PhotoMetadata.cs index 9c47d022e..c5502f707 100644 --- a/Jellyfin.Data/Entities/PhotoMetadata.cs +++ b/Jellyfin.Data/Entities/PhotoMetadata.cs @@ -1,86 +1,68 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class PhotoMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); + public partial class PhotoMetadata : Metadata + { + partial void Init(); - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected PhotoMetadata(): base() - { - Init(); - } + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected PhotoMetadata() + { + Init(); + } - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static PhotoMetadata CreatePhotoMetadataUnsafe() - { - return new PhotoMetadata(); - } + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static PhotoMetadata CreatePhotoMetadataUnsafe() + { + return new PhotoMetadata(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_photo0"></param> - public PhotoMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Photo _photo0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_photo0"></param> + public PhotoMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Photo _photo0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; - if (_photo0 == null) throw new ArgumentNullException(nameof(_photo0)); - _photo0.PhotoMetadata.Add(this); + if (_photo0 == null) throw new ArgumentNullException(nameof(_photo0)); + _photo0.PhotoMetadata.Add(this); - Init(); - } + Init(); + } - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_photo0"></param> - public static PhotoMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Photo _photo0) - { - return new PhotoMetadata(title, language, dateadded, datemodified, _photo0); - } + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_photo0"></param> + public static PhotoMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Photo _photo0) + { + return new PhotoMetadata(title, language, dateadded, datemodified, _photo0); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Preference.cs b/Jellyfin.Data/Entities/Preference.cs index 3d69ea2f3..505f52e6b 100644 --- a/Jellyfin.Data/Entities/Preference.cs +++ b/Jellyfin.Data/Entities/Preference.cs @@ -1,117 +1,107 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Preference - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Preference() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Preference CreatePreferenceUnsafe() - { - return new Preference(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="kind"></param> - /// <param name="value"></param> - /// <param name="_user0"></param> - /// <param name="_group1"></param> - public Preference(global::Jellyfin.Data.Enums.PreferenceKind kind, string value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1) - { - this.Kind = kind; - - if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(value)); - this.Value = value; - - if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); - _user0.Preferences.Add(this); - - if (_group1 == null) throw new ArgumentNullException(nameof(_group1)); - _group1.Preferences.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="kind"></param> - /// <param name="value"></param> - /// <param name="_user0"></param> - /// <param name="_group1"></param> - public static Preference Create(global::Jellyfin.Data.Enums.PreferenceKind kind, string value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1) - { - return new Preference(kind, value, _user0, _group1); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id { get; protected set; } - - /// <summary> - /// Required - /// </summary> - [Required] - public global::Jellyfin.Data.Enums.PreferenceKind Kind { get; set; } - - /// <summary> - /// Required, Max length = 65535 - /// </summary> - [Required] - [MaxLength(65535)] - [StringLength(65535)] - public string Value { get; set; } - - /// <summary> - /// Concurrency token - /// </summary> - [Timestamp] - public Byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - } + public partial class Preference + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Preference() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Preference CreatePreferenceUnsafe() + { + return new Preference(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="kind"></param> + /// <param name="value"></param> + /// <param name="_user0"></param> + /// <param name="_group1"></param> + public Preference(Enums.PreferenceKind kind, string value, User _user0, Group _group1) + { + this.Kind = kind; + + if (string.IsNullOrEmpty(value)) throw new ArgumentNullException(nameof(value)); + this.Value = value; + + if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); + _user0.Preferences.Add(this); + + if (_group1 == null) throw new ArgumentNullException(nameof(_group1)); + _group1.Preferences.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="kind"></param> + /// <param name="value"></param> + /// <param name="_user0"></param> + /// <param name="_group1"></param> + public static Preference Create(Enums.PreferenceKind kind, string value, User _user0, Group _group1) + { + return new Preference(kind, value, _user0, _group1); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; protected set; } + + /// <summary> + /// Required + /// </summary> + [Required] + public Enums.PreferenceKind Kind { get; set; } + + /// <summary> + /// Required, Max length = 65535 + /// </summary> + [Required] + [MaxLength(65535)] + [StringLength(65535)] + public string Value { get; set; } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + } } diff --git a/Jellyfin.Data/Entities/PreferenceKind.cs b/Jellyfin.Data/Entities/PreferenceKind.cs deleted file mode 100644 index e6673afb1..000000000 --- a/Jellyfin.Data/Entities/PreferenceKind.cs +++ /dev/null @@ -1,27 +0,0 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; - -namespace Jellyfin.Data.Enums -{ - public enum PreferenceKind : Int32 - { - MaxParentalRating, - BlockedTags, - RemoteClientBitrateLimit, - EnabledDevices, - EnabledChannels, - EnabledFolders, - EnableContentDeletionFromFolders - } -} diff --git a/Jellyfin.Data/Entities/ProviderMapping.cs b/Jellyfin.Data/Entities/ProviderMapping.cs index e50a01489..6197bd97b 100644 --- a/Jellyfin.Data/Entities/ProviderMapping.cs +++ b/Jellyfin.Data/Entities/ProviderMapping.cs @@ -1,133 +1,123 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class ProviderMapping - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected ProviderMapping() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static ProviderMapping CreateProviderMappingUnsafe() - { - return new ProviderMapping(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="providername"></param> - /// <param name="providersecrets"></param> - /// <param name="providerdata"></param> - /// <param name="_user0"></param> - /// <param name="_group1"></param> - public ProviderMapping(string providername, string providersecrets, string providerdata, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1) - { - if (string.IsNullOrEmpty(providername)) throw new ArgumentNullException(nameof(providername)); - this.ProviderName = providername; - - if (string.IsNullOrEmpty(providersecrets)) throw new ArgumentNullException(nameof(providersecrets)); - this.ProviderSecrets = providersecrets; - - if (string.IsNullOrEmpty(providerdata)) throw new ArgumentNullException(nameof(providerdata)); - this.ProviderData = providerdata; - - if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); - _user0.ProviderMappings.Add(this); - - if (_group1 == null) throw new ArgumentNullException(nameof(_group1)); - _group1.ProviderMappings.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="providername"></param> - /// <param name="providersecrets"></param> - /// <param name="providerdata"></param> - /// <param name="_user0"></param> - /// <param name="_group1"></param> - public static ProviderMapping Create(string providername, string providersecrets, string providerdata, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1) - { - return new ProviderMapping(providername, providersecrets, providerdata, _user0, _group1); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id { get; protected set; } - - /// <summary> - /// Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string ProviderName { get; set; } - - /// <summary> - /// Required, Max length = 65535 - /// </summary> - [Required] - [MaxLength(65535)] - [StringLength(65535)] - public string ProviderSecrets { get; set; } - - /// <summary> - /// Required, Max length = 65535 - /// </summary> - [Required] - [MaxLength(65535)] - [StringLength(65535)] - public string ProviderData { get; set; } - - /// <summary> - /// Concurrency token - /// </summary> - [Timestamp] - public Byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - } + public partial class ProviderMapping + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected ProviderMapping() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static ProviderMapping CreateProviderMappingUnsafe() + { + return new ProviderMapping(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="providername"></param> + /// <param name="providersecrets"></param> + /// <param name="providerdata"></param> + /// <param name="_user0"></param> + /// <param name="_group1"></param> + public ProviderMapping(string providername, string providersecrets, string providerdata, User _user0, Group _group1) + { + if (string.IsNullOrEmpty(providername)) throw new ArgumentNullException(nameof(providername)); + this.ProviderName = providername; + + if (string.IsNullOrEmpty(providersecrets)) throw new ArgumentNullException(nameof(providersecrets)); + this.ProviderSecrets = providersecrets; + + if (string.IsNullOrEmpty(providerdata)) throw new ArgumentNullException(nameof(providerdata)); + this.ProviderData = providerdata; + + if (_user0 == null) throw new ArgumentNullException(nameof(_user0)); + _user0.ProviderMappings.Add(this); + + if (_group1 == null) throw new ArgumentNullException(nameof(_group1)); + _group1.ProviderMappings.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="providername"></param> + /// <param name="providersecrets"></param> + /// <param name="providerdata"></param> + /// <param name="_user0"></param> + /// <param name="_group1"></param> + public static ProviderMapping Create(string providername, string providersecrets, string providerdata, User _user0, Group _group1) + { + return new ProviderMapping(providername, providersecrets, providerdata, _user0, _group1); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; protected set; } + + /// <summary> + /// Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string ProviderName { get; set; } + + /// <summary> + /// Required, Max length = 65535 + /// </summary> + [Required] + [MaxLength(65535)] + [StringLength(65535)] + public string ProviderSecrets { get; set; } + + /// <summary> + /// Required, Max length = 65535 + /// </summary> + [Required] + [MaxLength(65535)] + [StringLength(65535)] + public string ProviderData { get; set; } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + } } diff --git a/Jellyfin.Data/Entities/Rating.cs b/Jellyfin.Data/Entities/Rating.cs index b1098a1d7..f70ea8b33 100644 --- a/Jellyfin.Data/Entities/Rating.cs +++ b/Jellyfin.Data/Entities/Rating.cs @@ -1,197 +1,187 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Rating - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Rating() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Rating CreateRatingUnsafe() - { - return new Rating(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="value"></param> - /// <param name="_metadata0"></param> - public Rating(double value, global::Jellyfin.Data.Entities.Metadata _metadata0) - { - this.Value = value; - - if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); - _metadata0.Ratings.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="value"></param> - /// <param name="_metadata0"></param> - public static Rating Create(double value, global::Jellyfin.Data.Entities.Metadata _metadata0) - { - return new Rating(value, _metadata0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class Rating + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Rating() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Rating CreateRatingUnsafe() + { + return new Rating(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="value"></param> + /// <param name="_metadata0"></param> + public Rating(double value, Metadata _metadata0) + { + this.Value = value; + + if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0)); + _metadata0.Ratings.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="value"></param> + /// <param name="_metadata0"></param> + public static Rating Create(double value, Metadata _metadata0) + { + return new Rating(value, _metadata0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get + { + int value = _Id; + GetId(ref value); + return (_Id = value); + } + protected set + { + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } + } + } + + /// <summary> + /// Backing field for Value + /// </summary> + protected double _Value; + /// <summary> + /// When provided in a partial class, allows value of Value to be changed before setting. + /// </summary> + partial void SetValue(double oldValue, ref double newValue); + /// <summary> + /// When provided in a partial class, allows value of Value to be changed before returning. + /// </summary> + partial void GetValue(ref double result); + + /// <summary> + /// Required + /// </summary> + [Required] + public double Value + { + get + { + double value = _Value; + GetValue(ref value); + return (_Value = value); + } + set { - _Id = value; + double oldValue = _Value; + SetValue(oldValue, ref value); + if (oldValue != value) + { + _Value = value; + } } - } - } - - /// <summary> - /// Backing field for Value - /// </summary> - protected double _Value; - /// <summary> - /// When provided in a partial class, allows value of Value to be changed before setting. - /// </summary> - partial void SetValue(double oldValue, ref double newValue); - /// <summary> - /// When provided in a partial class, allows value of Value to be changed before returning. - /// </summary> - partial void GetValue(ref double result); - - /// <summary> - /// Required - /// </summary> - [Required] - public double Value - { - get - { - double value = _Value; - GetValue(ref value); - return (_Value = value); - } - set - { - double oldValue = _Value; - SetValue(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Votes + /// </summary> + protected int? _Votes; + /// <summary> + /// When provided in a partial class, allows value of Votes to be changed before setting. + /// </summary> + partial void SetVotes(int? oldValue, ref int? newValue); + /// <summary> + /// When provided in a partial class, allows value of Votes to be changed before returning. + /// </summary> + partial void GetVotes(ref int? result); + + public int? Votes + { + get { - _Value = value; + int? value = _Votes; + GetVotes(ref value); + return (_Votes = value); } - } - } - - /// <summary> - /// Backing field for Votes - /// </summary> - protected int? _Votes; - /// <summary> - /// When provided in a partial class, allows value of Votes to be changed before setting. - /// </summary> - partial void SetVotes(int? oldValue, ref int? newValue); - /// <summary> - /// When provided in a partial class, allows value of Votes to be changed before returning. - /// </summary> - partial void GetVotes(ref int? result); - - public int? Votes - { - get - { - int? value = _Votes; - GetVotes(ref value); - return (_Votes = value); - } - set - { - int? oldValue = _Votes; - SetVotes(oldValue, ref value); - if (oldValue != value) + set { - _Votes = value; + int? oldValue = _Votes; + SetVotes(oldValue, ref value); + if (oldValue != value) + { + _Votes = value; + } } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - /// <summary> - /// If this is NULL it's the internal user rating. - /// </summary> - public virtual global::Jellyfin.Data.Entities.RatingSource RatingType { get; set; } - - } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + + /// <summary> + /// If this is NULL it's the internal user rating. + /// </summary> + [ForeignKey("RatingSource_RatingType_Id")] + public virtual RatingSource RatingType { get; set; } + + } } diff --git a/Jellyfin.Data/Entities/RatingSource.cs b/Jellyfin.Data/Entities/RatingSource.cs index 32d5634c2..070f1ae27 100644 --- a/Jellyfin.Data/Entities/RatingSource.cs +++ b/Jellyfin.Data/Entities/RatingSource.cs @@ -1,242 +1,231 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - /// <summary> - /// This is the entity to store review ratings, not age ratings - /// </summary> - public partial class RatingSource - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected RatingSource() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static RatingSource CreateRatingSourceUnsafe() - { - return new RatingSource(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="maximumvalue"></param> - /// <param name="minimumvalue"></param> - /// <param name="_rating0"></param> - public RatingSource(double maximumvalue, double minimumvalue, global::Jellyfin.Data.Entities.Rating _rating0) - { - this.MaximumValue = maximumvalue; - - this.MinimumValue = minimumvalue; - - if (_rating0 == null) throw new ArgumentNullException(nameof(_rating0)); - _rating0.RatingType = this; - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="maximumvalue"></param> - /// <param name="minimumvalue"></param> - /// <param name="_rating0"></param> - public static RatingSource Create(double maximumvalue, double minimumvalue, global::Jellyfin.Data.Entities.Rating _rating0) - { - return new RatingSource(maximumvalue, minimumvalue, _rating0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + /// <summary> + /// This is the entity to store review ratings, not age ratings + /// </summary> + public partial class RatingSource + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected RatingSource() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static RatingSource CreateRatingSourceUnsafe() + { + return new RatingSource(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="maximumvalue"></param> + /// <param name="minimumvalue"></param> + /// <param name="_rating0"></param> + public RatingSource(double maximumvalue, double minimumvalue, Rating _rating0) + { + this.MaximumValue = maximumvalue; + + this.MinimumValue = minimumvalue; + + if (_rating0 == null) throw new ArgumentNullException(nameof(_rating0)); + _rating0.RatingType = this; + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="maximumvalue"></param> + /// <param name="minimumvalue"></param> + /// <param name="_rating0"></param> + public static RatingSource Create(double maximumvalue, double minimumvalue, Rating _rating0) + { + return new RatingSource(maximumvalue, minimumvalue, _rating0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get { - _Id = value; + int value = _Id; + GetId(ref value); + return (_Id = value); } - } - } - - /// <summary> - /// Backing field for Name - /// </summary> - protected string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + protected set { - _Name = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } - - /// <summary> - /// Backing field for MaximumValue - /// </summary> - protected double _MaximumValue; - /// <summary> - /// When provided in a partial class, allows value of MaximumValue to be changed before setting. - /// </summary> - partial void SetMaximumValue(double oldValue, ref double newValue); - /// <summary> - /// When provided in a partial class, allows value of MaximumValue to be changed before returning. - /// </summary> - partial void GetMaximumValue(ref double result); - - /// <summary> - /// Required - /// </summary> - [Required] - public double MaximumValue - { - get - { - double value = _MaximumValue; - GetMaximumValue(ref value); - return (_MaximumValue = value); - } - set - { - double oldValue = _MaximumValue; - SetMaximumValue(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Name + /// </summary> + protected string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Name + { + get { - _MaximumValue = value; + string value = _Name; + GetName(ref value); + return (_Name = value); } - } - } - - /// <summary> - /// Backing field for MinimumValue - /// </summary> - protected double _MinimumValue; - /// <summary> - /// When provided in a partial class, allows value of MinimumValue to be changed before setting. - /// </summary> - partial void SetMinimumValue(double oldValue, ref double newValue); - /// <summary> - /// When provided in a partial class, allows value of MinimumValue to be changed before returning. - /// </summary> - partial void GetMinimumValue(ref double result); - - /// <summary> - /// Required - /// </summary> - [Required] - public double MinimumValue - { - get - { - double value = _MinimumValue; - GetMinimumValue(ref value); - return (_MinimumValue = value); - } - set - { - double oldValue = _MinimumValue; - SetMinimumValue(oldValue, ref value); - if (oldValue != value) + set { - _MinimumValue = value; + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - public virtual global::Jellyfin.Data.Entities.MetadataProviderId Source { get; set; } - - } + } + + /// <summary> + /// Backing field for MaximumValue + /// </summary> + protected double _MaximumValue; + /// <summary> + /// When provided in a partial class, allows value of MaximumValue to be changed before setting. + /// </summary> + partial void SetMaximumValue(double oldValue, ref double newValue); + /// <summary> + /// When provided in a partial class, allows value of MaximumValue to be changed before returning. + /// </summary> + partial void GetMaximumValue(ref double result); + + /// <summary> + /// Required + /// </summary> + [Required] + public double MaximumValue + { + get + { + double value = _MaximumValue; + GetMaximumValue(ref value); + return (_MaximumValue = value); + } + set + { + double oldValue = _MaximumValue; + SetMaximumValue(oldValue, ref value); + if (oldValue != value) + { + _MaximumValue = value; + } + } + } + + /// <summary> + /// Backing field for MinimumValue + /// </summary> + protected double _MinimumValue; + /// <summary> + /// When provided in a partial class, allows value of MinimumValue to be changed before setting. + /// </summary> + partial void SetMinimumValue(double oldValue, ref double newValue); + /// <summary> + /// When provided in a partial class, allows value of MinimumValue to be changed before returning. + /// </summary> + partial void GetMinimumValue(ref double result); + + /// <summary> + /// Required + /// </summary> + [Required] + public double MinimumValue + { + get + { + double value = _MinimumValue; + GetMinimumValue(ref value); + return (_MinimumValue = value); + } + set + { + double oldValue = _MinimumValue; + SetMinimumValue(oldValue, ref value); + if (oldValue != value) + { + _MinimumValue = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("MetadataProviderId_Source_Id")] + public virtual MetadataProviderId Source { get; set; } + + } } diff --git a/Jellyfin.Data/Entities/Release.cs b/Jellyfin.Data/Entities/Release.cs index e02f70be8..d1928fcf7 100644 --- a/Jellyfin.Data/Entities/Release.cs +++ b/Jellyfin.Data/Entities/Release.cs @@ -1,197 +1,188 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Release - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Release() - { - MediaFiles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFile>(); - Chapters = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Chapter>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Release CreateReleaseUnsafe() - { - return new Release(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="name"></param> - /// <param name="_movie0"></param> - /// <param name="_episode1"></param> - /// <param name="_track2"></param> - /// <param name="_customitem3"></param> - /// <param name="_book4"></param> - /// <param name="_photo5"></param> - public Release(string name, global::Jellyfin.Data.Entities.Movie _movie0, global::Jellyfin.Data.Entities.Episode _episode1, global::Jellyfin.Data.Entities.Track _track2, global::Jellyfin.Data.Entities.CustomItem _customitem3, global::Jellyfin.Data.Entities.Book _book4, global::Jellyfin.Data.Entities.Photo _photo5) - { - if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); - this.Name = name; - - if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0)); - _movie0.Releases.Add(this); - - if (_episode1 == null) throw new ArgumentNullException(nameof(_episode1)); - _episode1.Releases.Add(this); - - if (_track2 == null) throw new ArgumentNullException(nameof(_track2)); - _track2.Releases.Add(this); - - if (_customitem3 == null) throw new ArgumentNullException(nameof(_customitem3)); - _customitem3.Releases.Add(this); - - if (_book4 == null) throw new ArgumentNullException(nameof(_book4)); - _book4.Releases.Add(this); - - if (_photo5 == null) throw new ArgumentNullException(nameof(_photo5)); - _photo5.Releases.Add(this); - - this.MediaFiles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFile>(); - this.Chapters = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Chapter>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="name"></param> - /// <param name="_movie0"></param> - /// <param name="_episode1"></param> - /// <param name="_track2"></param> - /// <param name="_customitem3"></param> - /// <param name="_book4"></param> - /// <param name="_photo5"></param> - public static Release Create(string name, global::Jellyfin.Data.Entities.Movie _movie0, global::Jellyfin.Data.Entities.Episode _episode1, global::Jellyfin.Data.Entities.Track _track2, global::Jellyfin.Data.Entities.CustomItem _customitem3, global::Jellyfin.Data.Entities.Book _book4, global::Jellyfin.Data.Entities.Photo _photo5) - { - return new Release(name, _movie0, _episode1, _track2, _customitem3, _book4, _photo5); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Id - /// </summary> - internal int _Id; - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before setting. - /// </summary> - partial void SetId(int oldValue, ref int newValue); - /// <summary> - /// When provided in a partial class, allows value of Id to be changed before returning. - /// </summary> - partial void GetId(ref int result); - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public int Id - { - get - { - int value = _Id; - GetId(ref value); - return (_Id = value); - } - protected set - { - int oldValue = _Id; - SetId(oldValue, ref value); - if (oldValue != value) + public partial class Release + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Release() + { + MediaFiles = new HashSet<MediaFile>(); + Chapters = new HashSet<Chapter>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Release CreateReleaseUnsafe() + { + return new Release(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="name"></param> + /// <param name="_movie0"></param> + /// <param name="_episode1"></param> + /// <param name="_track2"></param> + /// <param name="_customitem3"></param> + /// <param name="_book4"></param> + /// <param name="_photo5"></param> + public Release(string name, Movie _movie0, Episode _episode1, Track _track2, CustomItem _customitem3, Book _book4, Photo _photo5) + { + if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name)); + this.Name = name; + + if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0)); + _movie0.Releases.Add(this); + + if (_episode1 == null) throw new ArgumentNullException(nameof(_episode1)); + _episode1.Releases.Add(this); + + if (_track2 == null) throw new ArgumentNullException(nameof(_track2)); + _track2.Releases.Add(this); + + if (_customitem3 == null) throw new ArgumentNullException(nameof(_customitem3)); + _customitem3.Releases.Add(this); + + if (_book4 == null) throw new ArgumentNullException(nameof(_book4)); + _book4.Releases.Add(this); + + if (_photo5 == null) throw new ArgumentNullException(nameof(_photo5)); + _photo5.Releases.Add(this); + + this.MediaFiles = new HashSet<MediaFile>(); + this.Chapters = new HashSet<Chapter>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="name"></param> + /// <param name="_movie0"></param> + /// <param name="_episode1"></param> + /// <param name="_track2"></param> + /// <param name="_customitem3"></param> + /// <param name="_book4"></param> + /// <param name="_photo5"></param> + public static Release Create(string name, Movie _movie0, Episode _episode1, Track _track2, CustomItem _customitem3, Book _book4, Photo _photo5) + { + return new Release(name, _movie0, _episode1, _track2, _customitem3, _book4, _photo5); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Id + /// </summary> + internal int _Id; + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before setting. + /// </summary> + partial void SetId(int oldValue, ref int newValue); + /// <summary> + /// When provided in a partial class, allows value of Id to be changed before returning. + /// </summary> + partial void GetId(ref int result); + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id + { + get { - _Id = value; + int value = _Id; + GetId(ref value); + return (_Id = value); } - } - } - - /// <summary> - /// Backing field for Name - /// </summary> - protected string _Name; - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before setting. - /// </summary> - partial void SetName(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Name to be changed before returning. - /// </summary> - partial void GetName(ref string result); - - /// <summary> - /// Required, Max length = 1024 - /// </summary> - [Required] - [MaxLength(1024)] - [StringLength(1024)] - public string Name - { - get - { - string value = _Name; - GetName(ref value); - return (_Name = value); - } - set - { - string oldValue = _Name; - SetName(oldValue, ref value); - if (oldValue != value) + protected set { - _Name = value; + int oldValue = _Id; + SetId(oldValue, ref value); + if (oldValue != value) + { + _Id = value; + } } - } - } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] Timestamp { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - public virtual ICollection<global::Jellyfin.Data.Entities.MediaFile> MediaFiles { get; protected set; } - - public virtual ICollection<global::Jellyfin.Data.Entities.Chapter> Chapters { get; protected set; } - - } + } + + /// <summary> + /// Backing field for Name + /// </summary> + protected string _Name; + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before setting. + /// </summary> + partial void SetName(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Name to be changed before returning. + /// </summary> + partial void GetName(ref string result); + + /// <summary> + /// Required, Max length = 1024 + /// </summary> + [Required] + [MaxLength(1024)] + [StringLength(1024)] + public string Name + { + get + { + string value = _Name; + GetName(ref value); + return (_Name = value); + } + set + { + string oldValue = _Name; + SetName(oldValue, ref value); + if (oldValue != value) + { + _Name = value; + } + } + } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("MediaFile_MediaFiles_Id")] + public virtual ICollection<MediaFile> MediaFiles { get; protected set; } + + [ForeignKey("Chapter_Chapters_Id")] + public virtual ICollection<Chapter> Chapters { get; protected set; } + + } } diff --git a/Jellyfin.Data/Entities/Season.cs b/Jellyfin.Data/Entities/Season.cs index fdfdf2409..96e89cde0 100644 --- a/Jellyfin.Data/Entities/Season.cs +++ b/Jellyfin.Data/Entities/Season.cs @@ -1,127 +1,111 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Season: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Season(): base() - { - // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - SeasonMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeasonMetadata>(); - Episodes = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Episode>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Season CreateSeasonUnsafe() - { - return new Season(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - /// <param name="_series0"></param> - public Season(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Series _series0) - { - // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - this.UrlId = urlid; - - if (_series0 == null) throw new ArgumentNullException(nameof(_series0)); - _series0.Seasons.Add(this); - - this.SeasonMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeasonMetadata>(); - this.Episodes = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Episode>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - /// <param name="_series0"></param> - public static Season Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Series _series0) - { - return new Season(urlid, dateadded, _series0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for SeasonNumber - /// </summary> - protected int? _SeasonNumber; - /// <summary> - /// When provided in a partial class, allows value of SeasonNumber to be changed before setting. - /// </summary> - partial void SetSeasonNumber(int? oldValue, ref int? newValue); - /// <summary> - /// When provided in a partial class, allows value of SeasonNumber to be changed before returning. - /// </summary> - partial void GetSeasonNumber(ref int? result); - - public int? SeasonNumber - { - get - { - int? value = _SeasonNumber; - GetSeasonNumber(ref value); - return (_SeasonNumber = value); - } - set - { - int? oldValue = _SeasonNumber; - SetSeasonNumber(oldValue, ref value); - if (oldValue != value) + public partial class Season : LibraryItem + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Season() + { + // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + SeasonMetadata = new HashSet<SeasonMetadata>(); + Episodes = new HashSet<Episode>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Season CreateSeasonUnsafe() + { + return new Season(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + /// <param name="_series0"></param> + public Season(Guid urlid, DateTime dateadded, Series _series0) + { + // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + this.UrlId = urlid; + + if (_series0 == null) throw new ArgumentNullException(nameof(_series0)); + _series0.Seasons.Add(this); + + this.SeasonMetadata = new HashSet<SeasonMetadata>(); + this.Episodes = new HashSet<Episode>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + /// <param name="_series0"></param> + public static Season Create(Guid urlid, DateTime dateadded, Series _series0) + { + return new Season(urlid, dateadded, _series0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for SeasonNumber + /// </summary> + protected int? _SeasonNumber; + /// <summary> + /// When provided in a partial class, allows value of SeasonNumber to be changed before setting. + /// </summary> + partial void SetSeasonNumber(int? oldValue, ref int? newValue); + /// <summary> + /// When provided in a partial class, allows value of SeasonNumber to be changed before returning. + /// </summary> + partial void GetSeasonNumber(ref int? result); + + public int? SeasonNumber + { + get { - _SeasonNumber = value; + int? value = _SeasonNumber; + GetSeasonNumber(ref value); + return (_SeasonNumber = value); } - } - } - - /************************************************************************* - * Navigation properties - *************************************************************************/ + set + { + int? oldValue = _SeasonNumber; + SetSeasonNumber(oldValue, ref value); + if (oldValue != value) + { + _SeasonNumber = value; + } + } + } - public virtual ICollection<global::Jellyfin.Data.Entities.SeasonMetadata> SeasonMetadata { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("SeasonMetadata_SeasonMetadata_Id")] + public virtual ICollection<SeasonMetadata> SeasonMetadata { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Episode> Episodes { get; protected set; } + [ForeignKey("Episode_Episodes_Id")] + public virtual ICollection<Episode> Episodes { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/SeasonMetadata.cs b/Jellyfin.Data/Entities/SeasonMetadata.cs index 5939cbbca..64ecbfbfa 100644 --- a/Jellyfin.Data/Entities/SeasonMetadata.cs +++ b/Jellyfin.Data/Entities/SeasonMetadata.cs @@ -1,123 +1,106 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class SeasonMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected SeasonMetadata(): base() - { - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static SeasonMetadata CreateSeasonMetadataUnsafe() - { - return new SeasonMetadata(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_season0"></param> - public SeasonMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Season _season0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - if (_season0 == null) throw new ArgumentNullException(nameof(_season0)); - _season0.SeasonMetadata.Add(this); - - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_season0"></param> - public static SeasonMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Season _season0) - { - return new SeasonMetadata(title, language, dateadded, datemodified, _season0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Outline - /// </summary> - protected string _Outline; - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before setting. - /// </summary> - partial void SetOutline(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before returning. - /// </summary> - partial void GetOutline(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Outline - { - get - { - string value = _Outline; - GetOutline(ref value); - return (_Outline = value); - } - set - { - string oldValue = _Outline; - SetOutline(oldValue, ref value); - if (oldValue != value) + public partial class SeasonMetadata : Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected SeasonMetadata() + { + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static SeasonMetadata CreateSeasonMetadataUnsafe() + { + return new SeasonMetadata(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_season0"></param> + public SeasonMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Season _season0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + if (_season0 == null) throw new ArgumentNullException(nameof(_season0)); + _season0.SeasonMetadata.Add(this); + + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_season0"></param> + public static SeasonMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Season _season0) + { + return new SeasonMetadata(title, language, dateadded, datemodified, _season0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Outline + /// </summary> + protected string _Outline; + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before setting. + /// </summary> + partial void SetOutline(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before returning. + /// </summary> + partial void GetOutline(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Outline + { + get + { + string value = _Outline; + GetOutline(ref value); + return (_Outline = value); + } + set { - _Outline = value; + string oldValue = _Outline; + SetOutline(oldValue, ref value); + if (oldValue != value) + { + _Outline = value; + } } - } - } + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/Series.cs b/Jellyfin.Data/Entities/Series.cs index a57064824..097b9958e 100644 --- a/Jellyfin.Data/Entities/Series.cs +++ b/Jellyfin.Data/Entities/Series.cs @@ -1,183 +1,167 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Series: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Series(): base() - { - SeriesMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeriesMetadata>(); - Seasons = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Season>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Series CreateSeriesUnsafe() - { - return new Series(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public Series(Guid urlid, DateTime dateadded) - { - this.UrlId = urlid; - - this.SeriesMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.SeriesMetadata>(); - this.Seasons = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Season>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - public static Series Create(Guid urlid, DateTime dateadded) - { - return new Series(urlid, dateadded); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for AirsDayOfWeek - /// </summary> - protected global::Jellyfin.Data.Enums.Weekday? _AirsDayOfWeek; - /// <summary> - /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before setting. - /// </summary> - partial void SetAirsDayOfWeek(global::Jellyfin.Data.Enums.Weekday? oldValue, ref global::Jellyfin.Data.Enums.Weekday? newValue); - /// <summary> - /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before returning. - /// </summary> - partial void GetAirsDayOfWeek(ref global::Jellyfin.Data.Enums.Weekday? result); - - public global::Jellyfin.Data.Enums.Weekday? AirsDayOfWeek - { - get - { - global::Jellyfin.Data.Enums.Weekday? value = _AirsDayOfWeek; - GetAirsDayOfWeek(ref value); - return (_AirsDayOfWeek = value); - } - set - { - global::Jellyfin.Data.Enums.Weekday? oldValue = _AirsDayOfWeek; - SetAirsDayOfWeek(oldValue, ref value); - if (oldValue != value) + public partial class Series : LibraryItem + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Series() + { + SeriesMetadata = new HashSet<SeriesMetadata>(); + Seasons = new HashSet<Season>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Series CreateSeriesUnsafe() + { + return new Series(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public Series(Guid urlid, DateTime dateadded) + { + this.UrlId = urlid; + + this.SeriesMetadata = new HashSet<SeriesMetadata>(); + this.Seasons = new HashSet<Season>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + public static Series Create(Guid urlid, DateTime dateadded) + { + return new Series(urlid, dateadded); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for AirsDayOfWeek + /// </summary> + protected Enums.Weekday? _AirsDayOfWeek; + /// <summary> + /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before setting. + /// </summary> + partial void SetAirsDayOfWeek(Enums.Weekday? oldValue, ref Enums.Weekday? newValue); + /// <summary> + /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before returning. + /// </summary> + partial void GetAirsDayOfWeek(ref Enums.Weekday? result); + + public Enums.Weekday? AirsDayOfWeek + { + get { - _AirsDayOfWeek = value; + Enums.Weekday? value = _AirsDayOfWeek; + GetAirsDayOfWeek(ref value); + return (_AirsDayOfWeek = value); } - } - } - - /// <summary> - /// Backing field for AirsTime - /// </summary> - protected DateTimeOffset? _AirsTime; - /// <summary> - /// When provided in a partial class, allows value of AirsTime to be changed before setting. - /// </summary> - partial void SetAirsTime(DateTimeOffset? oldValue, ref DateTimeOffset? newValue); - /// <summary> - /// When provided in a partial class, allows value of AirsTime to be changed before returning. - /// </summary> - partial void GetAirsTime(ref DateTimeOffset? result); - - /// <summary> - /// The time the show airs, ignore the date portion - /// </summary> - public DateTimeOffset? AirsTime - { - get - { - DateTimeOffset? value = _AirsTime; - GetAirsTime(ref value); - return (_AirsTime = value); - } - set - { - DateTimeOffset? oldValue = _AirsTime; - SetAirsTime(oldValue, ref value); - if (oldValue != value) + set { - _AirsTime = value; + Enums.Weekday? oldValue = _AirsDayOfWeek; + SetAirsDayOfWeek(oldValue, ref value); + if (oldValue != value) + { + _AirsDayOfWeek = value; + } } - } - } - - /// <summary> - /// Backing field for FirstAired - /// </summary> - protected DateTimeOffset? _FirstAired; - /// <summary> - /// When provided in a partial class, allows value of FirstAired to be changed before setting. - /// </summary> - partial void SetFirstAired(DateTimeOffset? oldValue, ref DateTimeOffset? newValue); - /// <summary> - /// When provided in a partial class, allows value of FirstAired to be changed before returning. - /// </summary> - partial void GetFirstAired(ref DateTimeOffset? result); - - public DateTimeOffset? FirstAired - { - get - { - DateTimeOffset? value = _FirstAired; - GetFirstAired(ref value); - return (_FirstAired = value); - } - set - { - DateTimeOffset? oldValue = _FirstAired; - SetFirstAired(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for AirsTime + /// </summary> + protected DateTimeOffset? _AirsTime; + /// <summary> + /// When provided in a partial class, allows value of AirsTime to be changed before setting. + /// </summary> + partial void SetAirsTime(DateTimeOffset? oldValue, ref DateTimeOffset? newValue); + /// <summary> + /// When provided in a partial class, allows value of AirsTime to be changed before returning. + /// </summary> + partial void GetAirsTime(ref DateTimeOffset? result); + + /// <summary> + /// The time the show airs, ignore the date portion + /// </summary> + public DateTimeOffset? AirsTime + { + get { - _FirstAired = value; + DateTimeOffset? value = _AirsTime; + GetAirsTime(ref value); + return (_AirsTime = value); } - } - } - - /************************************************************************* - * Navigation properties - *************************************************************************/ + set + { + DateTimeOffset? oldValue = _AirsTime; + SetAirsTime(oldValue, ref value); + if (oldValue != value) + { + _AirsTime = value; + } + } + } + + /// <summary> + /// Backing field for FirstAired + /// </summary> + protected DateTimeOffset? _FirstAired; + /// <summary> + /// When provided in a partial class, allows value of FirstAired to be changed before setting. + /// </summary> + partial void SetFirstAired(DateTimeOffset? oldValue, ref DateTimeOffset? newValue); + /// <summary> + /// When provided in a partial class, allows value of FirstAired to be changed before returning. + /// </summary> + partial void GetFirstAired(ref DateTimeOffset? result); + + public DateTimeOffset? FirstAired + { + get + { + DateTimeOffset? value = _FirstAired; + GetFirstAired(ref value); + return (_FirstAired = value); + } + set + { + DateTimeOffset? oldValue = _FirstAired; + SetFirstAired(oldValue, ref value); + if (oldValue != value) + { + _FirstAired = value; + } + } + } - public virtual ICollection<global::Jellyfin.Data.Entities.SeriesMetadata> SeriesMetadata { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("SeriesMetadata_SeriesMetadata_Id")] + public virtual ICollection<SeriesMetadata> SeriesMetadata { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.Season> Seasons { get; protected set; } + [ForeignKey("Season_Seasons_Id")] + public virtual ICollection<Season> Seasons { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/SeriesMetadata.cs b/Jellyfin.Data/Entities/SeriesMetadata.cs index 9a91371df..52691783f 100644 --- a/Jellyfin.Data/Entities/SeriesMetadata.cs +++ b/Jellyfin.Data/Entities/SeriesMetadata.cs @@ -1,239 +1,223 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class SeriesMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected SeriesMetadata(): base() - { - Networks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static SeriesMetadata CreateSeriesMetadataUnsafe() - { - return new SeriesMetadata(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_series0"></param> - public SeriesMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Series _series0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; - - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; - - if (_series0 == null) throw new ArgumentNullException(nameof(_series0)); - _series0.SeriesMetadata.Add(this); - - this.Networks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_series0"></param> - public static SeriesMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Series _series0) - { - return new SeriesMetadata(title, language, dateadded, datemodified, _series0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for Outline - /// </summary> - protected string _Outline; - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before setting. - /// </summary> - partial void SetOutline(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Outline to be changed before returning. - /// </summary> - partial void GetOutline(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Outline - { - get - { - string value = _Outline; - GetOutline(ref value); - return (_Outline = value); - } - set - { - string oldValue = _Outline; - SetOutline(oldValue, ref value); - if (oldValue != value) + public partial class SeriesMetadata : Metadata + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected SeriesMetadata() + { + Networks = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static SeriesMetadata CreateSeriesMetadataUnsafe() + { + return new SeriesMetadata(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_series0"></param> + public SeriesMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Series _series0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; + + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; + + if (_series0 == null) throw new ArgumentNullException(nameof(_series0)); + _series0.SeriesMetadata.Add(this); + + this.Networks = new HashSet<Company>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_series0"></param> + public static SeriesMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Series _series0) + { + return new SeriesMetadata(title, language, dateadded, datemodified, _series0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for Outline + /// </summary> + protected string _Outline; + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before setting. + /// </summary> + partial void SetOutline(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Outline to be changed before returning. + /// </summary> + partial void GetOutline(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Outline + { + get { - _Outline = value; + string value = _Outline; + GetOutline(ref value); + return (_Outline = value); } - } - } - - /// <summary> - /// Backing field for Plot - /// </summary> - protected string _Plot; - /// <summary> - /// When provided in a partial class, allows value of Plot to be changed before setting. - /// </summary> - partial void SetPlot(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Plot to be changed before returning. - /// </summary> - partial void GetPlot(ref string result); - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string Plot - { - get - { - string value = _Plot; - GetPlot(ref value); - return (_Plot = value); - } - set - { - string oldValue = _Plot; - SetPlot(oldValue, ref value); - if (oldValue != value) + set { - _Plot = value; + string oldValue = _Outline; + SetOutline(oldValue, ref value); + if (oldValue != value) + { + _Outline = value; + } } - } - } - - /// <summary> - /// Backing field for Tagline - /// </summary> - protected string _Tagline; - /// <summary> - /// When provided in a partial class, allows value of Tagline to be changed before setting. - /// </summary> - partial void SetTagline(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Tagline to be changed before returning. - /// </summary> - partial void GetTagline(ref string result); - - /// <summary> - /// Max length = 1024 - /// </summary> - [MaxLength(1024)] - [StringLength(1024)] - public string Tagline - { - get - { - string value = _Tagline; - GetTagline(ref value); - return (_Tagline = value); - } - set - { - string oldValue = _Tagline; - SetTagline(oldValue, ref value); - if (oldValue != value) + } + + /// <summary> + /// Backing field for Plot + /// </summary> + protected string _Plot; + /// <summary> + /// When provided in a partial class, allows value of Plot to be changed before setting. + /// </summary> + partial void SetPlot(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Plot to be changed before returning. + /// </summary> + partial void GetPlot(ref string result); + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string Plot + { + get { - _Tagline = value; + string value = _Plot; + GetPlot(ref value); + return (_Plot = value); } - } - } - - /// <summary> - /// Backing field for Country - /// </summary> - protected string _Country; - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before setting. - /// </summary> - partial void SetCountry(string oldValue, ref string newValue); - /// <summary> - /// When provided in a partial class, allows value of Country to be changed before returning. - /// </summary> - partial void GetCountry(ref string result); - - /// <summary> - /// Max length = 2 - /// </summary> - [MaxLength(2)] - [StringLength(2)] - public string Country - { - get - { - string value = _Country; - GetCountry(ref value); - return (_Country = value); - } - set - { - string oldValue = _Country; - SetCountry(oldValue, ref value); - if (oldValue != value) + set { - _Country = value; + string oldValue = _Plot; + SetPlot(oldValue, ref value); + if (oldValue != value) + { + _Plot = value; + } } - } - } - - /************************************************************************* - * Navigation properties - *************************************************************************/ + } + + /// <summary> + /// Backing field for Tagline + /// </summary> + protected string _Tagline; + /// <summary> + /// When provided in a partial class, allows value of Tagline to be changed before setting. + /// </summary> + partial void SetTagline(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Tagline to be changed before returning. + /// </summary> + partial void GetTagline(ref string result); + + /// <summary> + /// Max length = 1024 + /// </summary> + [MaxLength(1024)] + [StringLength(1024)] + public string Tagline + { + get + { + string value = _Tagline; + GetTagline(ref value); + return (_Tagline = value); + } + set + { + string oldValue = _Tagline; + SetTagline(oldValue, ref value); + if (oldValue != value) + { + _Tagline = value; + } + } + } + + /// <summary> + /// Backing field for Country + /// </summary> + protected string _Country; + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before setting. + /// </summary> + partial void SetCountry(string oldValue, ref string newValue); + /// <summary> + /// When provided in a partial class, allows value of Country to be changed before returning. + /// </summary> + partial void GetCountry(ref string result); + + /// <summary> + /// Max length = 2 + /// </summary> + [MaxLength(2)] + [StringLength(2)] + public string Country + { + get + { + string value = _Country; + GetCountry(ref value); + return (_Country = value); + } + set + { + string oldValue = _Country; + SetCountry(oldValue, ref value); + if (oldValue != value) + { + _Country = value; + } + } + } - public virtual ICollection<global::Jellyfin.Data.Entities.Company> Networks { get; protected set; } + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("Company_Networks_Id")] + public virtual ICollection<Company> Networks { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/Track.cs b/Jellyfin.Data/Entities/Track.cs index 1d3ad372f..079d73d2b 100644 --- a/Jellyfin.Data/Entities/Track.cs +++ b/Jellyfin.Data/Entities/Track.cs @@ -1,127 +1,112 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class Track: global::Jellyfin.Data.Entities.LibraryItem - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected Track(): base() - { - // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); - TrackMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.TrackMetadata>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static Track CreateTrackUnsafe() - { - return new Track(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - /// <param name="_musicalbum0"></param> - public Track(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0) - { - // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. - // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. - - this.UrlId = urlid; - - if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0)); - _musicalbum0.Tracks.Add(this); - - this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>(); - this.TrackMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.TrackMetadata>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> - /// <param name="_musicalbum0"></param> - public static Track Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0) - { - return new Track(urlid, dateadded, _musicalbum0); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Backing field for TrackNumber - /// </summary> - protected int? _TrackNumber; - /// <summary> - /// When provided in a partial class, allows value of TrackNumber to be changed before setting. - /// </summary> - partial void SetTrackNumber(int? oldValue, ref int? newValue); - /// <summary> - /// When provided in a partial class, allows value of TrackNumber to be changed before returning. - /// </summary> - partial void GetTrackNumber(ref int? result); - - public int? TrackNumber - { - get - { - int? value = _TrackNumber; - GetTrackNumber(ref value); - return (_TrackNumber = value); - } - set - { - int? oldValue = _TrackNumber; - SetTrackNumber(oldValue, ref value); - if (oldValue != value) + public partial class Track : LibraryItem + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected Track() + { + // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + Releases = new HashSet<Release>(); + TrackMetadata = new HashSet<TrackMetadata>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static Track CreateTrackUnsafe() + { + return new Track(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + /// <param name="_musicalbum0"></param> + public Track(Guid urlid, DateTime dateadded, MusicAlbum _musicalbum0) + { + // NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem. + // One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other. + + this.UrlId = urlid; + + if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0)); + _musicalbum0.Tracks.Add(this); + + this.Releases = new HashSet<Release>(); + this.TrackMetadata = new HashSet<TrackMetadata>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param> + /// <param name="_musicalbum0"></param> + public static Track Create(Guid urlid, DateTime dateadded, MusicAlbum _musicalbum0) + { + return new Track(urlid, dateadded, _musicalbum0); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Backing field for TrackNumber + /// </summary> + protected int? _TrackNumber; + /// <summary> + /// When provided in a partial class, allows value of TrackNumber to be changed before setting. + /// </summary> + partial void SetTrackNumber(int? oldValue, ref int? newValue); + /// <summary> + /// When provided in a partial class, allows value of TrackNumber to be changed before returning. + /// </summary> + partial void GetTrackNumber(ref int? result); + + public int? TrackNumber + { + get + { + int? value = _TrackNumber; + GetTrackNumber(ref value); + return (_TrackNumber = value); + } + set { - _TrackNumber = value; + int? oldValue = _TrackNumber; + SetTrackNumber(oldValue, ref value); + if (oldValue != value) + { + _TrackNumber = value; + } } - } - } + } - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; } + [ForeignKey("Release_Releases_Id")] + public virtual ICollection<Release> Releases { get; protected set; } - public virtual ICollection<global::Jellyfin.Data.Entities.TrackMetadata> TrackMetadata { get; protected set; } + [ForeignKey("TrackMetadata_TrackMetadata_Id")] + public virtual ICollection<TrackMetadata> TrackMetadata { get; protected set; } - } + } } diff --git a/Jellyfin.Data/Entities/TrackMetadata.cs b/Jellyfin.Data/Entities/TrackMetadata.cs index f4c61459c..86c9161f6 100644 --- a/Jellyfin.Data/Entities/TrackMetadata.cs +++ b/Jellyfin.Data/Entities/TrackMetadata.cs @@ -1,86 +1,68 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class TrackMetadata: global::Jellyfin.Data.Entities.Metadata - { - partial void Init(); + public partial class TrackMetadata : Metadata + { + partial void Init(); - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected TrackMetadata(): base() - { - Init(); - } + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected TrackMetadata() + { + Init(); + } - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static TrackMetadata CreateTrackMetadataUnsafe() - { - return new TrackMetadata(); - } + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static TrackMetadata CreateTrackMetadataUnsafe() + { + return new TrackMetadata(); + } - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_track0"></param> - public TrackMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Track _track0) - { - if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); - this.Title = title; + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_track0"></param> + public TrackMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Track _track0) + { + if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title)); + this.Title = title; - if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); - this.Language = language; + if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language)); + this.Language = language; - if (_track0 == null) throw new ArgumentNullException(nameof(_track0)); - _track0.TrackMetadata.Add(this); + if (_track0 == null) throw new ArgumentNullException(nameof(_track0)); + _track0.TrackMetadata.Add(this); - Init(); - } + Init(); + } - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="title">The title or name of the object</param> - /// <param name="language">ISO-639-3 3-character language codes</param> - /// <param name="_track0"></param> - public static TrackMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Track _track0) - { - return new TrackMetadata(title, language, dateadded, datemodified, _track0); - } + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="title">The title or name of the object</param> + /// <param name="language">ISO-639-3 3-character language codes</param> + /// <param name="_track0"></param> + public static TrackMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Track _track0) + { + return new TrackMetadata(title, language, dateadded, datemodified, _track0); + } - /************************************************************************* - * Properties - *************************************************************************/ + /************************************************************************* + * Properties + *************************************************************************/ - /************************************************************************* - * Navigation properties - *************************************************************************/ + /************************************************************************* + * Navigation properties + *************************************************************************/ - } + } } diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs index 2ee3c8f4f..a81d5215b 100644 --- a/Jellyfin.Data/Entities/User.cs +++ b/Jellyfin.Data/Entities/User.cs @@ -1,242 +1,235 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Runtime.CompilerServices; namespace Jellyfin.Data.Entities { - public partial class User - { - partial void Init(); - - /// <summary> - /// Default constructor. Protected due to required properties, but present because EF needs it. - /// </summary> - protected User() - { - Groups = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Group>(); - Permissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>(); - ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>(); - Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>(); - - Init(); - } - - /// <summary> - /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. - /// </summary> - public static User CreateUserUnsafe() - { - return new User(); - } - - /// <summary> - /// Public constructor with required data - /// </summary> - /// <param name="username"></param> - /// <param name="mustupdatepassword"></param> - /// <param name="audiolanguagepreference"></param> - /// <param name="authenticationproviderid"></param> - /// <param name="invalidloginattemptcount"></param> - /// <param name="subtitlemode"></param> - /// <param name="playdefaultaudiotrack"></param> - public User(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack) - { - if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username)); - this.Username = username; - - this.MustUpdatePassword = mustupdatepassword; - - if (string.IsNullOrEmpty(audiolanguagepreference)) throw new ArgumentNullException(nameof(audiolanguagepreference)); - this.AudioLanguagePreference = audiolanguagepreference; - - if (string.IsNullOrEmpty(authenticationproviderid)) throw new ArgumentNullException(nameof(authenticationproviderid)); - this.AuthenticationProviderId = authenticationproviderid; - - this.InvalidLoginAttemptCount = invalidloginattemptcount; - - if (string.IsNullOrEmpty(subtitlemode)) throw new ArgumentNullException(nameof(subtitlemode)); - this.SubtitleMode = subtitlemode; - - this.PlayDefaultAudioTrack = playdefaultaudiotrack; - - this.Groups = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Group>(); - this.Permissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>(); - this.ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>(); - this.Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>(); - - Init(); - } - - /// <summary> - /// Static create function (for use in LINQ queries, etc.) - /// </summary> - /// <param name="username"></param> - /// <param name="mustupdatepassword"></param> - /// <param name="audiolanguagepreference"></param> - /// <param name="authenticationproviderid"></param> - /// <param name="invalidloginattemptcount"></param> - /// <param name="subtitlemode"></param> - /// <param name="playdefaultaudiotrack"></param> - public static User Create(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack) - { - return new User(username, mustupdatepassword, audiolanguagepreference, authenticationproviderid, invalidloginattemptcount, subtitlemode, playdefaultaudiotrack); - } - - /************************************************************************* - * Properties - *************************************************************************/ - - /// <summary> - /// Identity, Indexed, Required - /// </summary> - [Key] - [Required] - public Guid Id { get; protected set; } - - /// <summary> - /// Required - /// </summary> - [ConcurrencyCheck] - [Required] - public byte[] LastLoginTimestamp { get; set; } - - /// <summary> - /// Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string Username { get; set; } - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string Password { get; set; } - - /// <summary> - /// Required - /// </summary> - [Required] - public bool MustUpdatePassword { get; set; } - - /// <summary> - /// Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string AudioLanguagePreference { get; set; } - - /// <summary> - /// Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string AuthenticationProviderId { get; set; } - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string GroupedFolders { get; set; } - - /// <summary> - /// Required - /// </summary> - [Required] - public int InvalidLoginAttemptCount { get; set; } - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string LatestItemExcludes { get; set; } - - public int? LoginAttemptsBeforeLockout { get; set; } - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string MyMediaExcludes { get; set; } - - /// <summary> - /// Max length = 65535 - /// </summary> - [MaxLength(65535)] - [StringLength(65535)] - public string OrderedViews { get; set; } - - /// <summary> - /// Required, Max length = 255 - /// </summary> - [Required] - [MaxLength(255)] - [StringLength(255)] - public string SubtitleMode { get; set; } - - /// <summary> - /// Required - /// </summary> - [Required] - public bool PlayDefaultAudioTrack { get; set; } - - /// <summary> - /// Max length = 255 - /// </summary> - [MaxLength(255)] - [StringLength(255)] - public string SubtitleLanguagePrefernce { get; set; } - - public bool? DisplayMissingEpisodes { get; set; } - - public bool? DisplayCollectionsView { get; set; } - - public bool? HidePlayedInLatest { get; set; } - - public bool? RememberAudioSelections { get; set; } - - public bool? RememberSubtitleSelections { get; set; } - - public bool? EnableNextEpisodeAutoPlay { get; set; } - - public bool? EnableUserPreferenceAccess { get; set; } - - /************************************************************************* - * Navigation properties - *************************************************************************/ - - public virtual ICollection<global::Jellyfin.Data.Entities.Group> Groups { get; protected set; } - - public virtual ICollection<global::Jellyfin.Data.Entities.Permission> Permissions { get; protected set; } - - public virtual ICollection<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; protected set; } - - public virtual ICollection<global::Jellyfin.Data.Entities.Preference> Preferences { get; protected set; } - - } + public partial class User + { + partial void Init(); + + /// <summary> + /// Default constructor. Protected due to required properties, but present because EF needs it. + /// </summary> + protected User() + { + Groups = new HashSet<Group>(); + Permissions = new HashSet<Permission>(); + ProviderMappings = new HashSet<ProviderMapping>(); + Preferences = new HashSet<Preference>(); + + Init(); + } + + /// <summary> + /// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving. + /// </summary> + public static User CreateUserUnsafe() + { + return new User(); + } + + /// <summary> + /// Public constructor with required data + /// </summary> + /// <param name="username"></param> + /// <param name="mustupdatepassword"></param> + /// <param name="audiolanguagepreference"></param> + /// <param name="authenticationproviderid"></param> + /// <param name="invalidloginattemptcount"></param> + /// <param name="subtitlemode"></param> + /// <param name="playdefaultaudiotrack"></param> + public User(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack) + { + if (string.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username)); + this.Username = username; + + this.MustUpdatePassword = mustupdatepassword; + + if (string.IsNullOrEmpty(audiolanguagepreference)) throw new ArgumentNullException(nameof(audiolanguagepreference)); + this.AudioLanguagePreference = audiolanguagepreference; + + if (string.IsNullOrEmpty(authenticationproviderid)) throw new ArgumentNullException(nameof(authenticationproviderid)); + this.AuthenticationProviderId = authenticationproviderid; + + this.InvalidLoginAttemptCount = invalidloginattemptcount; + + if (string.IsNullOrEmpty(subtitlemode)) throw new ArgumentNullException(nameof(subtitlemode)); + this.SubtitleMode = subtitlemode; + + this.PlayDefaultAudioTrack = playdefaultaudiotrack; + + this.Groups = new HashSet<Group>(); + this.Permissions = new HashSet<Permission>(); + this.ProviderMappings = new HashSet<ProviderMapping>(); + this.Preferences = new HashSet<Preference>(); + + Init(); + } + + /// <summary> + /// Static create function (for use in LINQ queries, etc.) + /// </summary> + /// <param name="username"></param> + /// <param name="mustupdatepassword"></param> + /// <param name="audiolanguagepreference"></param> + /// <param name="authenticationproviderid"></param> + /// <param name="invalidloginattemptcount"></param> + /// <param name="subtitlemode"></param> + /// <param name="playdefaultaudiotrack"></param> + public static User Create(string username, bool mustupdatepassword, string audiolanguagepreference, string authenticationproviderid, int invalidloginattemptcount, string subtitlemode, bool playdefaultaudiotrack) + { + return new User(username, mustupdatepassword, audiolanguagepreference, authenticationproviderid, invalidloginattemptcount, subtitlemode, playdefaultaudiotrack); + } + + /************************************************************************* + * Properties + *************************************************************************/ + + /// <summary> + /// Identity, Indexed, Required + /// </summary> + [Key] + [Required] + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public int Id { get; protected set; } + + /// <summary> + /// Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string Username { get; set; } + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string Password { get; set; } + + /// <summary> + /// Required + /// </summary> + [Required] + public bool MustUpdatePassword { get; set; } + + /// <summary> + /// Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string AudioLanguagePreference { get; set; } + + /// <summary> + /// Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string AuthenticationProviderId { get; set; } + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string GroupedFolders { get; set; } + + /// <summary> + /// Required + /// </summary> + [Required] + public int InvalidLoginAttemptCount { get; set; } + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string LatestItemExcludes { get; set; } + + public int? LoginAttemptsBeforeLockout { get; set; } + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string MyMediaExcludes { get; set; } + + /// <summary> + /// Max length = 65535 + /// </summary> + [MaxLength(65535)] + [StringLength(65535)] + public string OrderedViews { get; set; } + + /// <summary> + /// Required, Max length = 255 + /// </summary> + [Required] + [MaxLength(255)] + [StringLength(255)] + public string SubtitleMode { get; set; } + + /// <summary> + /// Required + /// </summary> + [Required] + public bool PlayDefaultAudioTrack { get; set; } + + /// <summary> + /// Max length = 255 + /// </summary> + [MaxLength(255)] + [StringLength(255)] + public string SubtitleLanguagePrefernce { get; set; } + + public bool? DisplayMissingEpisodes { get; set; } + + public bool? DisplayCollectionsView { get; set; } + + public bool? HidePlayedInLatest { get; set; } + + public bool? RememberAudioSelections { get; set; } + + public bool? RememberSubtitleSelections { get; set; } + + public bool? EnableNextEpisodeAutoPlay { get; set; } + + public bool? EnableUserPreferenceAccess { get; set; } + + /// <summary> + /// Required, ConcurrenyToken + /// </summary> + [ConcurrencyCheck] + [Required] + public uint RowVersion { get; set; } + + public void OnSavingChanges() + { + RowVersion++; + } + + /************************************************************************* + * Navigation properties + *************************************************************************/ + [ForeignKey("Group_Groups_Id")] + public virtual ICollection<Group> Groups { get; protected set; } + + [ForeignKey("Permission_Permissions_Id")] + public virtual ICollection<Permission> Permissions { get; protected set; } + + [ForeignKey("ProviderMapping_ProviderMappings_Id")] + public virtual ICollection<ProviderMapping> ProviderMappings { get; protected set; } + + [ForeignKey("Preference_Preferences_Id")] + public virtual ICollection<Preference> Preferences { get; protected set; } + + } } diff --git a/Jellyfin.Data/Enums/ArtKind.cs b/Jellyfin.Data/Enums/ArtKind.cs index 52e33048e..6b69d68b2 100644 --- a/Jellyfin.Data/Enums/ArtKind.cs +++ b/Jellyfin.Data/Enums/ArtKind.cs @@ -1,25 +1,11 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; - namespace Jellyfin.Data.Enums { - public enum ArtKind : Int32 - { - Other, - Poster, - Banner, - Thumbnail, - Logo - } + public enum ArtKind + { + Other, + Poster, + Banner, + Thumbnail, + Logo + } } diff --git a/Jellyfin.Data/Enums/MediaFileKind.cs b/Jellyfin.Data/Enums/MediaFileKind.cs index 34d1b20f5..12f48c558 100644 --- a/Jellyfin.Data/Enums/MediaFileKind.cs +++ b/Jellyfin.Data/Enums/MediaFileKind.cs @@ -1,25 +1,11 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; - namespace Jellyfin.Data.Enums { - public enum MediaFileKind : Int32 - { - Main, - Sidecar, - AdditionalPart, - AlternativeFormat, - AdditionalStream - } + public enum MediaFileKind + { + Main, + Sidecar, + AdditionalPart, + AlternativeFormat, + AdditionalStream + } } diff --git a/Jellyfin.Data/Enums/PermissionKind.cs b/Jellyfin.Data/Enums/PermissionKind.cs new file mode 100644 index 000000000..1506471e8 --- /dev/null +++ b/Jellyfin.Data/Enums/PermissionKind.cs @@ -0,0 +1,26 @@ +namespace Jellyfin.Data.Enums +{ + public enum PermissionKind + { + IsAdministrator, + IsHidden, + IsDisabled, + BlockUnrateditems, + EnbleSharedDeviceControl, + EnableRemoteAccess, + EnableLiveTvManagement, + EnableLiveTvAccess, + EnableMediaPlayback, + EnableAudioPlaybackTranscoding, + EnableVideoPlaybackTranscoding, + EnableContentDeletion, + EnableContentDownloading, + EnableSyncTranscoding, + EnableMediaConversion, + EnableAllDevices, + EnableAllChannels, + EnableAllFolders, + EnablePublicSharing, + AccessSchedules + } +} diff --git a/Jellyfin.Data/Enums/PersonRoleType.cs b/Jellyfin.Data/Enums/PersonRoleType.cs index f5c8f43c5..6e52f2c85 100644 --- a/Jellyfin.Data/Enums/PersonRoleType.cs +++ b/Jellyfin.Data/Enums/PersonRoleType.cs @@ -1,32 +1,18 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; - namespace Jellyfin.Data.Enums { - public enum PersonRoleType : Int32 - { - Other, - Director, - Artist, - OriginalArtist, - Actor, - VoiceActor, - Producer, - Remixer, - Conductor, - Composer, - Author, - Editor - } + public enum PersonRoleType + { + Other, + Director, + Artist, + OriginalArtist, + Actor, + VoiceActor, + Producer, + Remixer, + Conductor, + Composer, + Author, + Editor + } } diff --git a/Jellyfin.Data/Enums/PreferenceKind.cs b/Jellyfin.Data/Enums/PreferenceKind.cs new file mode 100644 index 000000000..cd2cb791a --- /dev/null +++ b/Jellyfin.Data/Enums/PreferenceKind.cs @@ -0,0 +1,13 @@ +namespace Jellyfin.Data.Enums +{ + public enum PreferenceKind + { + MaxParentalRating, + BlockedTags, + RemoteClientBitrateLimit, + EnabledDevices, + EnabledChannels, + EnabledFolders, + EnableContentDeletionFromFolders + } +} diff --git a/Jellyfin.Data/Enums/Weekday.cs b/Jellyfin.Data/Enums/Weekday.cs index ce0c6e4ce..b80a03a33 100644 --- a/Jellyfin.Data/Enums/Weekday.cs +++ b/Jellyfin.Data/Enums/Weekday.cs @@ -1,27 +1,13 @@ -//------------------------------------------------------------------------------ -// <auto-generated> -// This code was generated from a template. -// -// Manual changes to this file may cause unexpected behavior in your application. -// Manual changes to this file will be overwritten if the code is regenerated. -// -// Produced by Entity Framework Visual Editor -// https://github.com/msawczyn/EFDesigner -// </auto-generated> -//------------------------------------------------------------------------------ - -using System; - namespace Jellyfin.Data.Enums { - public enum Weekday : Int32 - { - Sunday, - Monday, - Tuesday, - Wednesday, - Thursday, - Friday, - Saturday - } + public enum Weekday + { + Sunday, + Monday, + Tuesday, + Wednesday, + Thursday, + Friday, + Saturday + } } diff --git a/Jellyfin.Data/ISavingChanges.cs b/Jellyfin.Data/ISavingChanges.cs new file mode 100644 index 000000000..f392dae6a --- /dev/null +++ b/Jellyfin.Data/ISavingChanges.cs @@ -0,0 +1,9 @@ +#pragma warning disable CS1591 + +namespace Jellyfin.Data +{ + public interface ISavingChanges + { + void OnSavingChanges(); + } +} diff --git a/Jellyfin.Data/Structs/.gitkeep b/Jellyfin.Data/Structs/.gitkeep deleted file mode 100644 index e69de29bb..000000000 --- a/Jellyfin.Data/Structs/.gitkeep +++ /dev/null diff --git a/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj new file mode 100644 index 000000000..a31f28f64 --- /dev/null +++ b/Jellyfin.Server.Implementations/Jellyfin.Server.Implementations.csproj @@ -0,0 +1,34 @@ +<Project Sdk="Microsoft.NET.Sdk"> + + <PropertyGroup> + <TargetFramework>netcoreapp3.1</TargetFramework> + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> + <GenerateDocumentationFile>true</GenerateDocumentationFile> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + </PropertyGroup> + + <PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> + <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet> + </PropertyGroup> + + <!-- Code analysers--> + <ItemGroup Condition=" '$(Configuration)' == 'Debug' "> + <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" /> + <PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" /> + <PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" /> + <PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" /> + </ItemGroup> + + <ItemGroup> + <Compile Include="..\SharedVersion.cs" /> + <Compile Remove="Migrations\20200430214405_InitialSchema.cs" /> + <Compile Remove="Migrations\20200430214405_InitialSchema.Designer.cs" /> + </ItemGroup> + + <ItemGroup> + <ProjectReference Include="..\Jellyfin.Data\Jellyfin.Data.csproj" /> + <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" /> + <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" /> + </ItemGroup> + +</Project> diff --git a/Jellyfin.Server.Implementations/JellyfinDb.cs b/Jellyfin.Server.Implementations/JellyfinDb.cs new file mode 100644 index 000000000..76343edf9 --- /dev/null +++ b/Jellyfin.Server.Implementations/JellyfinDb.cs @@ -0,0 +1,115 @@ +#pragma warning disable CS1591 +#pragma warning disable SA1201 // Constuctors should not follow properties +#pragma warning disable SA1516 // Elements should be followed by a blank line +#pragma warning disable SA1623 // Property's documentation should begin with gets or sets +#pragma warning disable SA1629 // Documentation should end with a period +#pragma warning disable SA1648 // Inheritdoc should be used with inheriting class + +using System.Linq; +using Jellyfin.Data; +using Jellyfin.Data.Entities; +using Microsoft.EntityFrameworkCore; + +namespace Jellyfin.Server.Implementations +{ + /// <inheritdoc/> + public partial class JellyfinDb : DbContext + { + /*public virtual DbSet<Artwork> Artwork { get; set; } + public virtual DbSet<Book> Books { get; set; } + public virtual DbSet<BookMetadata> BookMetadata { get; set; } + public virtual DbSet<Chapter> Chapters { get; set; } + public virtual DbSet<Collection> Collections { get; set; } + public virtual DbSet<CollectionItem> CollectionItems { get; set; } + public virtual DbSet<Company> Companies { get; set; } + public virtual DbSet<CompanyMetadata> CompanyMetadata { get; set; } + public virtual DbSet<CustomItem> CustomItems { get; set; } + public virtual DbSet<CustomItemMetadata> CustomItemMetadata { get; set; } + public virtual DbSet<Episode> Episodes { get; set; } + public virtual DbSet<EpisodeMetadata> EpisodeMetadata { get; set; } + public virtual DbSet<Genre> Genres { get; set; } + public virtual DbSet<Group> Groups { get; set; } + public virtual DbSet<Library> Libraries { get; set; } + public virtual DbSet<LibraryItem> LibraryItems { get; set; } + public virtual DbSet<LibraryRoot> LibraryRoot { get; set; } + public virtual DbSet<MediaFile> MediaFiles { get; set; } + public virtual DbSet<MediaFileStream> MediaFileStream { get; set; } + public virtual DbSet<Metadata> Metadata { get; set; } + public virtual DbSet<MetadataProvider> MetadataProviders { get; set; } + public virtual DbSet<MetadataProviderId> MetadataProviderIds { get; set; } + public virtual DbSet<Movie> Movies { get; set; } + public virtual DbSet<MovieMetadata> MovieMetadata { get; set; } + public virtual DbSet<MusicAlbum> MusicAlbums { get; set; } + public virtual DbSet<MusicAlbumMetadata> MusicAlbumMetadata { get; set; } + public virtual DbSet<Permission> Permissions { get; set; } + public virtual DbSet<Person> People { get; set; } + public virtual DbSet<PersonRole> PersonRoles { get; set; } + public virtual DbSet<Photo> Photo { get; set; } + public virtual DbSet<PhotoMetadata> PhotoMetadata { get; set; } + public virtual DbSet<Preference> Preferences { get; set; } + public virtual DbSet<ProviderMapping> ProviderMappings { get; set; } + public virtual DbSet<Rating> Ratings { get; set; } + /// <summary> + /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to + /// store review ratings, not age ratings + /// </summary> + public virtual DbSet<RatingSource> RatingSources { get; set; } + public virtual DbSet<Release> Releases { get; set; } + public virtual DbSet<Season> Seasons { get; set; } + public virtual DbSet<SeasonMetadata> SeasonMetadata { get; set; } + public virtual DbSet<Series> Series { get; set; } + public virtual DbSet<SeriesMetadata> SeriesMetadata { get; set; } + public virtual DbSet<Track> Tracks { get; set; } + public virtual DbSet<TrackMetadata> TrackMetadata { get; set; } + public virtual DbSet<User> Users { get; set; } */ + + /// <summary> + /// Gets or sets the default connection string. + /// </summary> + public static string ConnectionString { get; set; } = @"Data Source=jellyfin.db"; + + /// <inheritdoc /> + public JellyfinDb(DbContextOptions<JellyfinDb> options) : base(options) + { + } + + partial void CustomInit(DbContextOptionsBuilder optionsBuilder); + + /// <inheritdoc /> + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + CustomInit(optionsBuilder); + } + + partial void OnModelCreatingImpl(ModelBuilder modelBuilder); + partial void OnModelCreatedImpl(ModelBuilder modelBuilder); + + /// <inheritdoc /> + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + OnModelCreatingImpl(modelBuilder); + + modelBuilder.HasDefaultSchema("jellyfin"); + + /*modelBuilder.Entity<Artwork>().HasIndex(t => t.Kind); + modelBuilder.Entity<Genre>().HasIndex(t => t.Name) + .IsUnique(); + modelBuilder.Entity<LibraryItem>().HasIndex(t => t.UrlId) + .IsUnique();*/ + + OnModelCreatedImpl(modelBuilder); + } + + public override int SaveChanges() + { + foreach (var entity in ChangeTracker.Entries().Where(e => e.State == EntityState.Modified)) + { + var saveEntity = entity.Entity as ISavingChanges; + saveEntity.OnSavingChanges(); + } + + return base.SaveChanges(); + } + } +} diff --git a/Jellyfin.Server/Migrations/IMigrationRoutine.cs b/Jellyfin.Server/Migrations/IMigrationRoutine.cs index eab995d67..b79fdeac0 100644 --- a/Jellyfin.Server/Migrations/IMigrationRoutine.cs +++ b/Jellyfin.Server/Migrations/IMigrationRoutine.cs @@ -21,8 +21,6 @@ namespace Jellyfin.Server.Migrations /// <summary> /// Execute the migration routine. /// </summary> - /// <param name="host">Host that hosts current version.</param> - /// <param name="logger">Host logger.</param> - public void Perform(CoreAppHost host, ILogger logger); + public void Perform(); } } diff --git a/Jellyfin.Server/Migrations/MigrationRunner.cs b/Jellyfin.Server/Migrations/MigrationRunner.cs index b5ea04dca..ca1748282 100644 --- a/Jellyfin.Server/Migrations/MigrationRunner.cs +++ b/Jellyfin.Server/Migrations/MigrationRunner.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using MediaBrowser.Common.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace Jellyfin.Server.Migrations @@ -13,10 +14,10 @@ namespace Jellyfin.Server.Migrations /// <summary> /// The list of known migrations, in order of applicability. /// </summary> - internal static readonly IMigrationRoutine[] Migrations = + private static readonly Type[] _migrationTypes = { - new Routines.DisableTranscodingThrottling(), - new Routines.CreateUserLoggingConfigFile() + typeof(Routines.DisableTranscodingThrottling), + typeof(Routines.CreateUserLoggingConfigFile) }; /// <summary> @@ -27,6 +28,10 @@ namespace Jellyfin.Server.Migrations public static void Run(CoreAppHost host, ILoggerFactory loggerFactory) { var logger = loggerFactory.CreateLogger<MigrationRunner>(); + var migrations = _migrationTypes + .Select(m => ActivatorUtilities.CreateInstance(host.ServiceProvider, m)) + .OfType<IMigrationRoutine>() + .ToArray(); var migrationOptions = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration<MigrationOptions>(MigrationsListStore.StoreKey); if (!host.ServerConfigurationManager.Configuration.IsStartupWizardCompleted && migrationOptions.Applied.Count == 0) @@ -34,16 +39,16 @@ namespace Jellyfin.Server.Migrations // If startup wizard is not finished, this is a fresh install. // Don't run any migrations, just mark all of them as applied. logger.LogInformation("Marking all known migrations as applied because this is a fresh install"); - migrationOptions.Applied.AddRange(Migrations.Select(m => (m.Id, m.Name))); + migrationOptions.Applied.AddRange(migrations.Select(m => (m.Id, m.Name))); host.ServerConfigurationManager.SaveConfiguration(MigrationsListStore.StoreKey, migrationOptions); return; } var appliedMigrationIds = migrationOptions.Applied.Select(m => m.Id).ToHashSet(); - for (var i = 0; i < Migrations.Length; i++) + for (var i = 0; i < migrations.Length; i++) { - var migrationRoutine = Migrations[i]; + var migrationRoutine = migrations[i]; if (appliedMigrationIds.Contains(migrationRoutine.Id)) { logger.LogDebug("Skipping migration '{Name}' since it is already applied", migrationRoutine.Name); @@ -54,7 +59,7 @@ namespace Jellyfin.Server.Migrations try { - migrationRoutine.Perform(host, logger); + migrationRoutine.Perform(); } catch (Exception ex) { diff --git a/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs b/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs index 3bc32c047..89514c89b 100644 --- a/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs +++ b/Jellyfin.Server/Migrations/Routines/CreateUserLoggingConfigFile.cs @@ -36,6 +36,13 @@ namespace Jellyfin.Server.Migrations.Routines @"{""Serilog"":{""MinimumLevel"":""Information"",""WriteTo"":[{""Name"":""Console"",""Args"":{""outputTemplate"":""[{Timestamp:HH:mm:ss}] [{Level:u3}] [{ThreadId}] {SourceContext}: {Message:lj}{NewLine}{Exception}""}},{""Name"":""Async"",""Args"":{""configure"":[{""Name"":""File"",""Args"":{""path"":""%JELLYFIN_LOG_DIR%//log_.log"",""rollingInterval"":""Day"",""retainedFileCountLimit"":3,""rollOnFileSizeLimit"":true,""fileSizeLimitBytes"":100000000,""outputTemplate"":""[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] [{ThreadId}] {SourceContext}:{Message}{NewLine}{Exception}""}}]}}],""Enrich"":[""FromLogContext"",""WithThreadId""]}}", }; + private readonly IApplicationPaths _appPaths; + + public CreateUserLoggingConfigFile(IApplicationPaths appPaths) + { + _appPaths = appPaths; + } + /// <inheritdoc/> public Guid Id => Guid.Parse("{EF103419-8451-40D8-9F34-D1A8E93A1679}"); @@ -43,9 +50,9 @@ namespace Jellyfin.Server.Migrations.Routines public string Name => "CreateLoggingConfigHeirarchy"; /// <inheritdoc/> - public void Perform(CoreAppHost host, ILogger logger) + public void Perform() { - var logDirectory = host.Resolve<IApplicationPaths>().ConfigurationDirectoryPath; + var logDirectory = _appPaths.ConfigurationDirectoryPath; var existingConfigPath = Path.Combine(logDirectory, "logging.json"); // If the existing logging.json config file is unmodified, then 'reset' it by moving it to 'logging.old.json' diff --git a/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs b/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs index 6f8e4a8ff..b2e957d5b 100644 --- a/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs +++ b/Jellyfin.Server/Migrations/Routines/DisableTranscodingThrottling.cs @@ -10,6 +10,15 @@ namespace Jellyfin.Server.Migrations.Routines /// </summary> internal class DisableTranscodingThrottling : IMigrationRoutine { + private readonly ILogger _logger; + private readonly IConfigurationManager _configManager; + + public DisableTranscodingThrottling(ILogger<DisableTranscodingThrottling> logger, IConfigurationManager configManager) + { + _logger = logger; + _configManager = configManager; + } + /// <inheritdoc/> public Guid Id => Guid.Parse("{4124C2CD-E939-4FFB-9BE9-9B311C413638}"); @@ -17,16 +26,16 @@ namespace Jellyfin.Server.Migrations.Routines public string Name => "DisableTranscodingThrottling"; /// <inheritdoc/> - public void Perform(CoreAppHost host, ILogger logger) + public void Perform() { // Set EnableThrottling to false since it wasn't used before and may introduce issues - var encoding = ((IConfigurationManager)host.ServerConfigurationManager).GetConfiguration<EncodingOptions>("encoding"); + var encoding = _configManager.GetConfiguration<EncodingOptions>("encoding"); if (encoding.EnableThrottling) { - logger.LogInformation("Disabling transcoding throttling during migration"); + _logger.LogInformation("Disabling transcoding throttling during migration"); encoding.EnableThrottling = false; - host.ServerConfigurationManager.SaveConfiguration("encoding", encoding); + _configManager.SaveConfiguration("encoding", encoding); } } } diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index ae423532e..b9895386f 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -10,14 +10,11 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using CommandLine; -using Emby.Drawing; using Emby.Server.Implementations; using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.IO; using Emby.Server.Implementations.Networking; -using Jellyfin.Drawing.Skia; using MediaBrowser.Common.Configuration; -using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Extensions; using MediaBrowser.WebDashboard.Api; using Microsoft.AspNetCore.Hosting; @@ -297,7 +294,7 @@ namespace Jellyfin.Server { _logger.LogInformation("Kestrel listening on {IpAddress}", address); options.Listen(address, appHost.HttpPort); - if (appHost.EnableHttps && appHost.Certificate != null) + if (appHost.ListenWithHttps) { options.Listen(address, appHost.HttpsPort, listenOptions => { @@ -327,7 +324,7 @@ namespace Jellyfin.Server _logger.LogInformation("Kestrel listening on all interfaces"); options.ListenAnyIP(appHost.HttpPort); - if (appHost.EnableHttps && appHost.Certificate != null) + if (appHost.ListenWithHttps) { options.ListenAnyIP(appHost.HttpsPort, listenOptions => { diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 8bcfd1350..5f9a5c161 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -64,7 +64,6 @@ namespace Jellyfin.Server app.UseResponseCompression(); // TODO app.UseMiddleware<WebSocketMiddleware>(); - app.Use(serverApplicationHost.ExecuteWebsocketHandlerAsync); // TODO use when old API is removed: app.UseAuthentication(); app.UseJellyfinApiSwagger(); diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs index 1a1d86362..2cd68ac1b 100644 --- a/MediaBrowser.Api/BaseApiService.cs +++ b/MediaBrowser.Api/BaseApiService.cs @@ -21,7 +21,7 @@ namespace MediaBrowser.Api public abstract class BaseApiService : IService, IRequiresRequest { public BaseApiService( - ILogger logger, + ILogger<BaseApiService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory) { @@ -34,7 +34,7 @@ namespace MediaBrowser.Api /// Gets the logger. /// </summary> /// <value>The logger.</value> - protected ILogger Logger { get; } + protected ILogger<BaseApiService> Logger { get; } /// <summary> /// Gets or sets the server configuration manager. diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index a54640b2f..2d1977d2e 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -319,11 +319,14 @@ namespace MediaBrowser.Api.Library private readonly ILocalizationManager _localization; private readonly ILibraryMonitor _libraryMonitor; + private readonly ILogger<MoviesService> _moviesServiceLogger; + /// <summary> /// Initializes a new instance of the <see cref="LibraryService" /> class. /// </summary> public LibraryService( ILogger<LibraryService> logger, + ILogger<MoviesService> moviesServiceLogger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IProviderManager providerManager, @@ -344,6 +347,7 @@ namespace MediaBrowser.Api.Library _activityManager = activityManager; _localization = localization; _libraryMonitor = libraryMonitor; + _moviesServiceLogger = moviesServiceLogger; } private string[] GetRepresentativeItemTypes(string contentType) @@ -543,7 +547,7 @@ namespace MediaBrowser.Api.Library if (item is Movie || (program != null && program.IsMovie) || item is Trailer) { return new MoviesService( - Logger, + _moviesServiceLogger, ServerConfigurationManager, ResultFactory, _userManager, diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs index 46da8b909..cdd027634 100644 --- a/MediaBrowser.Api/Movies/MoviesService.cs +++ b/MediaBrowser.Api/Movies/MoviesService.cs @@ -82,7 +82,7 @@ namespace MediaBrowser.Api.Movies /// Initializes a new instance of the <see cref="MoviesService" /> class. /// </summary> public MoviesService( - ILogger logger, + ILogger<MoviesService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, diff --git a/MediaBrowser.Api/Movies/TrailersService.cs b/MediaBrowser.Api/Movies/TrailersService.cs index 8adf9c621..0b5334235 100644 --- a/MediaBrowser.Api/Movies/TrailersService.cs +++ b/MediaBrowser.Api/Movies/TrailersService.cs @@ -33,13 +33,18 @@ namespace MediaBrowser.Api.Movies /// </summary> private readonly ILibraryManager _libraryManager; + /// <summary> + /// The logger for the created <see cref="ItemsService"/> instances. + /// </summary> + private readonly ILogger<ItemsService> _logger; + private readonly IDtoService _dtoService; private readonly ILocalizationManager _localizationManager; private readonly IJsonSerializer _json; private readonly IAuthorizationContext _authContext; public TrailersService( - ILogger<TrailersService> logger, + ILoggerFactory loggerFactory, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, @@ -48,7 +53,7 @@ namespace MediaBrowser.Api.Movies ILocalizationManager localizationManager, IJsonSerializer json, IAuthorizationContext authContext) - : base(logger, serverConfigurationManager, httpResultFactory) + : base(loggerFactory.CreateLogger<TrailersService>(), serverConfigurationManager, httpResultFactory) { _userManager = userManager; _libraryManager = libraryManager; @@ -56,6 +61,7 @@ namespace MediaBrowser.Api.Movies _localizationManager = localizationManager; _json = json; _authContext = authContext; + _logger = loggerFactory.CreateLogger<ItemsService>(); } public object Get(Getrailers request) @@ -66,7 +72,7 @@ namespace MediaBrowser.Api.Movies getItems.IncludeItemTypes = "Trailer"; return new ItemsService( - Logger, + _logger, ServerConfigurationManager, ResultFactory, _userManager, diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 928ca1612..f796aa486 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -81,7 +81,7 @@ namespace MediaBrowser.Api.Playback /// Initializes a new instance of the <see cref="BaseStreamingService" /> class. /// </summary> protected BaseStreamingService( - ILogger logger, + ILogger<BaseStreamingService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 4213193ba..627421aac 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -25,7 +25,7 @@ namespace MediaBrowser.Api.Playback.Hls public abstract class BaseHlsService : BaseStreamingService { public BaseHlsService( - ILogger logger, + ILogger<BaseHlsService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 7f74e85e9..061316cb8 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -94,7 +94,7 @@ namespace MediaBrowser.Api.Playback.Hls public class DynamicHlsService : BaseHlsService { public DynamicHlsService( - ILogger logger, + ILogger<DynamicHlsService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index db24eaca6..e2d771ec6 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -79,7 +79,7 @@ namespace MediaBrowser.Api.Playback private readonly IAuthorizationContext _authContext; public MediaInfoService( - ILogger logger, + ILogger<MediaInfoService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IMediaSourceManager mediaSourceManager, diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index 8d1e3a3f2..34c7986ca 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Api.Playback.Progressive public class AudioService : BaseProgressiveStreamingService { public AudioService( - ILogger logger, + ILogger<AudioService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IHttpClient httpClient, diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index ed68219c9..c7bf055fb 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Api.Playback.Progressive protected IHttpClient HttpClient { get; private set; } public BaseProgressiveStreamingService( - ILogger logger, + ILogger<BaseProgressiveStreamingService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IHttpClient httpClient, diff --git a/MediaBrowser.Api/Playback/UniversalAudioService.cs b/MediaBrowser.Api/Playback/UniversalAudioService.cs index cebd4b49a..a3b319d44 100644 --- a/MediaBrowser.Api/Playback/UniversalAudioService.cs +++ b/MediaBrowser.Api/Playback/UniversalAudioService.cs @@ -75,9 +75,11 @@ namespace MediaBrowser.Api.Playback public class UniversalAudioService : BaseApiService { private readonly EncodingHelper _encodingHelper; + private readonly ILoggerFactory _loggerFactory; public UniversalAudioService( ILogger<UniversalAudioService> logger, + ILoggerFactory loggerFactory, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IHttpClient httpClient, @@ -108,6 +110,7 @@ namespace MediaBrowser.Api.Playback AuthorizationContext = authorizationContext; NetworkManager = networkManager; _encodingHelper = encodingHelper; + _loggerFactory = loggerFactory; } protected IHttpClient HttpClient { get; private set; } @@ -233,7 +236,7 @@ namespace MediaBrowser.Api.Playback AuthorizationContext.GetAuthorizationInfo(Request).DeviceId = request.DeviceId; var mediaInfoService = new MediaInfoService( - Logger, + _loggerFactory.CreateLogger<MediaInfoService>(), ServerConfigurationManager, ResultFactory, MediaSourceManager, @@ -277,7 +280,7 @@ namespace MediaBrowser.Api.Playback if (!isStatic && string.Equals(mediaSource.TranscodingSubProtocol, "hls", StringComparison.OrdinalIgnoreCase)) { var service = new DynamicHlsService( - Logger, + _loggerFactory.CreateLogger<DynamicHlsService>(), ServerConfigurationManager, ResultFactory, UserManager, @@ -331,7 +334,7 @@ namespace MediaBrowser.Api.Playback else { var service = new AudioService( - Logger, + _loggerFactory.CreateLogger<AudioService>(), ServerConfigurationManager, ResultFactory, HttpClient, diff --git a/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs b/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs index d882aac88..0e74c9267 100644 --- a/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs +++ b/MediaBrowser.Api/Sessions/SessionInfoWebSocketListener.cs @@ -31,46 +31,46 @@ namespace MediaBrowser.Api.Sessions { _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.Sessions return Task.FromResult(_sessionManager.Sessions); } + /// <inheritdoc /> 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.Api/System/ActivityLogWebSocketListener.cs b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs index f8b6ee65d..8e4860be4 100644 --- a/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs +++ b/MediaBrowser.Api/System/ActivityLogWebSocketListener.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System; using System.Threading.Tasks; using MediaBrowser.Controller.Net; using MediaBrowser.Model.Activity; @@ -10,7 +10,7 @@ namespace MediaBrowser.Api.System /// <summary> /// Class SessionInfoWebSocketListener /// </summary> - public class ActivityLogWebSocketListener : BasePeriodicWebSocketListener<List<ActivityLogEntry>, WebSocketListenerState> + public class ActivityLogWebSocketListener : BasePeriodicWebSocketListener<ActivityLogEntry[], WebSocketListenerState> { /// <summary> /// Gets the name. @@ -26,10 +26,10 @@ namespace MediaBrowser.Api.System public ActivityLogWebSocketListener(ILogger<ActivityLogWebSocketListener> logger, IActivityManager activityManager) : base(logger) { _activityManager = activityManager; - _activityManager.EntryCreated += _activityManager_EntryCreated; + _activityManager.EntryCreated += OnEntryCreated; } - void _activityManager_EntryCreated(object sender, GenericEventArgs<ActivityLogEntry> e) + private void OnEntryCreated(object sender, GenericEventArgs<ActivityLogEntry> e) { SendData(true); } @@ -38,15 +38,15 @@ namespace MediaBrowser.Api.System /// Gets the data to send. /// </summary> /// <returns>Task{SystemInfo}.</returns> - protected override Task<List<ActivityLogEntry>> GetDataToSend() + protected override Task<ActivityLogEntry[]> GetDataToSend() { - return Task.FromResult(new List<ActivityLogEntry>()); + return Task.FromResult(Array.Empty<ActivityLogEntry>()); } - + /// <inheritdoc /> protected override void Dispose(bool dispose) { - _activityManager.EntryCreated -= _activityManager_EntryCreated; + _activityManager.EntryCreated -= OnEntryCreated; base.Dispose(dispose); } diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs index 3d08d5437..bef91d54d 100644 --- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs +++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs @@ -51,7 +51,7 @@ namespace MediaBrowser.Api.UserLibrary public class ArtistsService : BaseItemsByNameService<MusicArtist> { public ArtistsService( - ILogger<GenresService> logger, + ILogger<ArtistsService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index c4a52d5f5..559082ff4 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -28,7 +28,7 @@ namespace MediaBrowser.Api.UserLibrary /// <param name="userDataRepository">The user data repository.</param> /// <param name="dtoService">The dto service.</param> protected BaseItemsByNameService( - ILogger logger, + ILogger<BaseItemsByNameService<TItemType>> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index c4d44042b..f3c0441e1 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -59,7 +59,7 @@ namespace MediaBrowser.Api.UserLibrary /// <param name="localization">The localization.</param> /// <param name="dtoService">The dto service.</param> public ItemsService( - ILogger logger, + ILogger<ItemsService> logger, IServerConfigurationManager serverConfigurationManager, IHttpResultFactory httpResultFactory, IUserManager userManager, diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs index 04ba0fabc..d1d6c74b8 100644 --- a/MediaBrowser.Controller/IServerApplicationHost.cs +++ b/MediaBrowser.Controller/IServerApplicationHost.cs @@ -39,10 +39,9 @@ namespace MediaBrowser.Controller int HttpsPort { get; } /// <summary> - /// Gets a value indicating whether [supports HTTPS]. + /// Gets a value indicating whether the server should listen on an HTTPS port. /// </summary> - /// <value><c>true</c> if [supports HTTPS]; otherwise, <c>false</c>.</value> - bool EnableHttps { get; } + bool ListenWithHttps { get; } /// <summary> /// Gets a value indicating whether this instance has update available. @@ -57,34 +56,50 @@ namespace MediaBrowser.Controller string FriendlyName { get; } /// <summary> - /// Gets the local ip address. + /// Gets all the local IP addresses of this API instance. Each address is validated by sending a 'ping' request + /// to the API that should exist at the address. /// </summary> - /// <value>The local ip address.</value> + /// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param> + /// <returns>A list containing all the local IP addresses of the server.</returns> Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken); /// <summary> - /// Gets the local API URL. + /// Gets a local (LAN) URL that can be used to access the API. The hostname used is the first valid configured + /// IP address that can be found via <see cref="GetLocalIpAddresses"/>. HTTPS will be preferred when available. /// </summary> - /// <param name="cancellationToken">Token to cancel the request if needed.</param> - /// <param name="forceHttp">Whether to force usage of plain HTTP protocol.</param> - /// <value>The local API URL.</value> - Task<string> GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp = false); + /// <param name="cancellationToken">A cancellation token that can be used to cancel the task.</param> + /// <returns>The server URL.</returns> + Task<string> GetLocalApiUrl(CancellationToken cancellationToken); /// <summary> - /// Gets the local API URL. + /// Gets a localhost URL that can be used to access the API using the loop-back IP address (127.0.0.1) + /// over HTTP (not HTTPS). /// </summary> - /// <param name="hostname">The hostname.</param> - /// <param name="forceHttp">Whether to force usage of plain HTTP protocol.</param> - /// <returns>The local API URL.</returns> - string GetLocalApiUrl(ReadOnlySpan<char> hostname, bool forceHttp = false); + /// <returns>The API URL.</returns> + string GetLoopbackHttpApiUrl(); /// <summary> - /// Gets the local API URL. + /// Gets a local (LAN) URL that can be used to access the API. HTTPS will be preferred when available. /// </summary> - /// <param name="address">The IP address.</param> - /// <param name="forceHttp">Whether to force usage of plain HTTP protocol.</param> - /// <returns>The local API URL.</returns> - string GetLocalApiUrl(IPAddress address, bool forceHttp = false); + /// <param name="address">The IP address to use as the hostname in the URL.</param> + /// <returns>The API URL.</returns> + string GetLocalApiUrl(IPAddress address); + + /// <summary> + /// Gets a local (LAN) URL that can be used to access the API. + /// Note: if passing non-null scheme or port it is up to the caller to ensure they form the correct pair. + /// </summary> + /// <param name="hostname">The hostname to use in the URL.</param> + /// <param name="scheme"> + /// The scheme to use for the URL. If null, the scheme will be selected automatically, + /// preferring HTTPS, if available. + /// </param> + /// <param name="port"> + /// The port to use for the URL. If null, the port will be selected automatically, + /// preferring the HTTPS port, if available. + /// </param> + /// <returns>The API URL.</returns> + string GetLocalApiUrl(ReadOnlySpan<char> hostname, string scheme = null, int? port = null); /// <summary> /// Open a URL in an external browser window. @@ -101,7 +116,5 @@ namespace MediaBrowser.Controller string ReverseVirtualPath(string path); Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next); - - Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next); } } diff --git a/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs b/MediaBrowser.Controller/Net/BasePeriodicWebSocketListener.cs index b710318ee..1162bff13 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"); - /// <summary> /// Starts sending messages over a web socket /// </summary> @@ -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 { @@ -154,7 +152,6 @@ namespace MediaBrowser.Controller.Net { MessageType = Name, Data = data - }, cancellationToken).ConfigureAwait(false); state.DateLastSendUtc = DateTime.UtcNow; @@ -197,7 +194,7 @@ namespace MediaBrowser.Controller.Net /// <param name="connection">The connection.</param> private void DisposeConnection(Tuple<IWebSocketConnection, CancellationTokenSource, TStateType> 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(); @@ -242,6 +239,7 @@ namespace MediaBrowser.Controller.Net public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } } diff --git a/MediaBrowser.Controller/Net/IHttpServer.cs b/MediaBrowser.Controller/Net/IHttpServer.cs index 806478864..efb5f4ac3 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; @@ -9,9 +8,9 @@ using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net { /// <summary> - /// Interface IHttpServer + /// Interface IHttpServer. /// </summary> - public interface IHttpServer : IDisposable + public interface IHttpServer { /// <summary> /// Gets the URL prefix. @@ -20,11 +19,6 @@ namespace MediaBrowser.Controller.Net string[] UrlPrefixes { get; } /// <summary> - /// Stops this instance. - /// </summary> - void Stop(); - - /// <summary> /// Occurs when [web socket connected]. /// </summary> event EventHandler<GenericEventArgs<IWebSocketConnection>> WebSocketConnected; @@ -40,22 +34,17 @@ namespace MediaBrowser.Controller.Net string GlobalResponse { get; set; } /// <summary> - /// Sends the http context to the socket listener + /// The HTTP request handler /// </summary> - /// <param name="ctx"></param> + /// <param name="context"></param> /// <returns></returns> - Task ProcessWebSocketRequest(HttpContext ctx); + Task RequestHandler(HttpContext context); /// <summary> - /// The HTTP request handler + /// Get the default CORS headers /// </summary> - /// <param name="httpReq"></param> - /// <param name="urlString"></param> - /// <param name="host"></param> - /// <param name="localPath"></param> - /// <param name="cancellationToken"></param> + /// <param name="req"></param> /// <returns></returns> - Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, - CancellationToken cancellationToken); + IDictionary<string, string> GetDefaultCorsHeaders(IRequest req); } } diff --git a/MediaBrowser.Controller/Net/IWebSocketConnection.cs b/MediaBrowser.Controller/Net/IWebSocketConnection.cs index 31eb7ccb7..09e43c683 100644 --- a/MediaBrowser.Controller/Net/IWebSocketConnection.cs +++ b/MediaBrowser.Controller/Net/IWebSocketConnection.cs @@ -1,4 +1,7 @@ +#nullable enable + using System; +using System.Net; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; @@ -7,18 +10,12 @@ using Microsoft.AspNetCore.Http; namespace MediaBrowser.Controller.Net { - public interface IWebSocketConnection : IDisposable + public interface IWebSocketConnection { /// <summary> /// Occurs when [closed]. /// </summary> - event EventHandler<EventArgs> Closed; - - /// <summary> - /// Gets the id. - /// </summary> - /// <value>The id.</value> - Guid Id { get; } + event EventHandler<EventArgs>? Closed; /// <summary> /// Gets the last activity date. @@ -27,21 +24,16 @@ namespace MediaBrowser.Controller.Net DateTime LastActivityDate { get; } /// <summary> - /// Gets or sets the URL. - /// </summary> - /// <value>The URL.</value> - string Url { get; set; } - /// <summary> /// Gets or sets the query string. /// </summary> /// <value>The query string.</value> - IQueryCollection QueryString { get; set; } + IQueryCollection QueryString { get; } /// <summary> /// Gets or sets the receive action. /// </summary> /// <value>The receive action.</value> - Func<WebSocketMessageInfo, Task> OnReceive { get; set; } + Func<WebSocketMessageInfo, Task>? OnReceive { get; set; } /// <summary> /// Gets the state. @@ -53,7 +45,7 @@ namespace MediaBrowser.Controller.Net /// Gets the remote end point. /// </summary> /// <value>The remote end point.</value> - string RemoteEndPoint { get; } + IPAddress? RemoteEndPoint { get; } /// <summary> /// Sends a message asynchronously. @@ -65,21 +57,6 @@ namespace MediaBrowser.Controller.Net /// <exception cref="ArgumentNullException">message</exception> Task SendAsync<T>(WebSocketMessage<T> message, CancellationToken cancellationToken); - /// <summary> - /// Sends a message asynchronously. - /// </summary> - /// <param name="buffer">The buffer.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - Task SendAsync(byte[] buffer, CancellationToken cancellationToken); - - /// <summary> - /// Sends a message asynchronously. - /// </summary> - /// <param name="text">The text.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - /// <exception cref="ArgumentNullException">buffer</exception> - 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 a59c96ac7..04450085b 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 /// <summary> /// Sends the message. /// </summary> - Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken); + Task SendMessage<T>(string name, Guid messageId, T data, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index f1f10a3a3..2ba7c9fec 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 { /// <summary> - /// Class SessionInfo + /// Class SessionInfo. /// </summary> - 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 /// <value>The name of the device.</value> public string DeviceName { get; set; } - public string DeviceType { get; set; } - /// <summary> /// Gets or sets the now playing item. /// </summary> @@ -128,22 +136,6 @@ namespace MediaBrowser.Controller.Session [JsonIgnore] public ISessionController[] SessionControllers { get; set; } - /// <summary> - /// Gets or sets the supported commands. - /// </summary> - /// <value>The supported commands.</value> - public string[] SupportedCommands - { - get - { - if (Capabilities == null) - { - return new string[] { }; - } - return Capabilities.SupportedCommands; - } - } - public TranscodingInfo TranscodingInfo { get; set; } /// <summary> @@ -215,6 +207,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<ISessionController, bool> EnsureController<T>(Func<SessionInfo, ISessionController> factory) { var controllers = SessionControllers.ToList(); @@ -258,10 +258,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) @@ -284,9 +280,6 @@ namespace MediaBrowser.Controller.Session } } - // 1 second - private const long ProgressIncrement = 10000000; - private async void OnProgressTimerCallback(object state) { if (_disposed) @@ -345,8 +338,7 @@ namespace MediaBrowser.Controller.Session } } - private bool _disposed = false; - + /// <inheritdoc /> public void Dispose() { _disposed = true; @@ -358,30 +350,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/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index 063ccd9b9..22a42322a 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -49,17 +49,24 @@ namespace MediaBrowser.Model.Configuration public int HttpsPortNumber { get; set; } /// <summary> - /// Gets or sets a value indicating whether [use HTTPS]. + /// Gets or sets a value indicating whether to use HTTPS. /// </summary> - /// <value><c>true</c> if [use HTTPS]; otherwise, <c>false</c>.</value> + /// <remarks> + /// In order for HTTPS to be used, in addition to setting this to true, valid values must also be + /// provided for <see cref="CertificatePath"/> and <see cref="CertificatePassword"/>. + /// </remarks> public bool EnableHttps { get; set; } + public bool EnableNormalizedItemByNameIds { get; set; } /// <summary> - /// Gets or sets the value pointing to the file system where the ssl certificate is located.. + /// Gets or sets the filesystem path of an X.509 certificate to use for SSL. /// </summary> - /// <value>The value pointing to the file system where the ssl certificate is located..</value> public string CertificatePath { get; set; } + + /// <summary> + /// Gets or sets the password required to access the X.509 certificate data in the file specified by <see cref="CertificatePath"/>. + /// </summary> public string CertificatePassword { get; set; } /// <summary> @@ -69,8 +76,11 @@ namespace MediaBrowser.Model.Configuration public bool IsPortAuthorized { get; set; } public bool AutoRunWebApp { get; set; } + public bool EnableRemoteAccess { get; set; } + public bool CameraUploadUpgraded { get; set; } + public bool CollectionsUpgraded { get; set; } /// <summary> @@ -86,6 +96,7 @@ namespace MediaBrowser.Model.Configuration /// </summary> /// <value>The metadata path.</value> public string MetadataPath { get; set; } + public string MetadataNetworkPath { get; set; } /// <summary> @@ -208,15 +219,26 @@ namespace MediaBrowser.Model.Configuration public int RemoteClientBitrateLimit { get; set; } public bool EnableFolderView { get; set; } + public bool EnableGroupingIntoCollections { get; set; } + public bool DisplaySpecialsWithinSeasons { get; set; } + public string[] LocalNetworkSubnets { get; set; } + public string[] LocalNetworkAddresses { get; set; } + public string[] CodecsUsed { get; set; } + public bool IgnoreVirtualInterfaces { get; set; } + public bool EnableExternalContentInSuggestions { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the server should force connections over HTTPS. + /// </summary> public bool RequireHttps { get; set; } - public bool IsBehindProxy { get; set; } + public bool EnableNewOmdbSupport { get; set; } public string[] RemoteIPFilter { get; set; } diff --git a/MediaBrowser.Model/Net/WebSocketMessage.cs b/MediaBrowser.Model/Net/WebSocketMessage.cs index 7575224d4..03f03e4cc 100644 --- a/MediaBrowser.Model/Net/WebSocketMessage.cs +++ b/MediaBrowser.Model/Net/WebSocketMessage.cs @@ -1,5 +1,8 @@ + #pragma warning disable CS1591 +using System; + namespace MediaBrowser.Model.Net { /// <summary> @@ -13,7 +16,9 @@ namespace MediaBrowser.Model.Net /// </summary> /// <value>The type of the message.</value> public string MessageType { get; set; } - public string MessageId { get; set; } + + public Guid MessageId { get; set; } + public string ServerId { get; set; } /// <summary> @@ -22,5 +27,4 @@ namespace MediaBrowser.Model.Net /// <value>The data.</value> public T Data { get; set; } } - } diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs index 3d543039e..f2c5aa1e3 100644 --- a/MediaBrowser.Model/System/SystemInfo.cs +++ b/MediaBrowser.Model/System/SystemInfo.cs @@ -116,24 +116,6 @@ namespace MediaBrowser.Model.System public string TranscodingTempPath { get; set; } /// <summary> - /// Gets or sets the HTTP server port number. - /// </summary> - /// <value>The HTTP server port number.</value> - public int HttpServerPortNumber { get; set; } - - /// <summary> - /// Gets or sets a value indicating whether [enable HTTPS]. - /// </summary> - /// <value><c>true</c> if [enable HTTPS]; otherwise, <c>false</c>.</value> - public bool SupportsHttps { get; set; } - - /// <summary> - /// Gets or sets the HTTPS server port number. - /// </summary> - /// <value>The HTTPS server port number.</value> - public int HttpsPortNumber { get; set; } - - /// <summary> /// Gets or sets a value indicating whether this instance has update available. /// </summary> /// <value><c>true</c> if this instance has update available; otherwise, <c>false</c>.</value> diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs index 37160dd2c..f0328e8d8 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbEpisodeProvider.cs @@ -11,13 +11,10 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; -using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Plugins.Omdb { - public class OmdbEpisodeProvider : - IRemoteMetadataProvider<Episode, EpisodeInfo>, - IHasOrder + public class OmdbEpisodeProvider : IRemoteMetadataProvider<Episode, EpisodeInfo>, IHasOrder { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; @@ -26,16 +23,27 @@ namespace MediaBrowser.Providers.Plugins.Omdb private readonly IServerConfigurationManager _configurationManager; private readonly IApplicationHost _appHost; - public OmdbEpisodeProvider(IJsonSerializer jsonSerializer, IApplicationHost appHost, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager configurationManager) + public OmdbEpisodeProvider( + IJsonSerializer jsonSerializer, + IApplicationHost appHost, + IHttpClient httpClient, + ILibraryManager libraryManager, + IFileSystem fileSystem, + IServerConfigurationManager configurationManager) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; _fileSystem = fileSystem; _configurationManager = configurationManager; _appHost = appHost; - _itemProvider = new OmdbItemProvider(jsonSerializer, _appHost, httpClient, logger, libraryManager, fileSystem, configurationManager); + _itemProvider = new OmdbItemProvider(jsonSerializer, _appHost, httpClient, libraryManager, fileSystem, configurationManager); } + // After TheTvDb + public int Order => 1; + + public string Name => "The Open Movie Database"; + public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(EpisodeInfo searchInfo, CancellationToken cancellationToken) { return _itemProvider.GetSearchResults(searchInfo, "episode", cancellationToken); @@ -66,10 +74,6 @@ namespace MediaBrowser.Providers.Plugins.Omdb return result; } - // After TheTvDb - public int Order => 1; - - public string Name => "The Open Movie Database"; public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken) { diff --git a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs index 3aadda5d0..64a75955a 100644 --- a/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs +++ b/MediaBrowser.Providers/Plugins/Omdb/OmdbItemProvider.cs @@ -17,7 +17,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Providers; using MediaBrowser.Model.Serialization; -using Microsoft.Extensions.Logging; namespace MediaBrowser.Providers.Plugins.Omdb { @@ -26,22 +25,27 @@ namespace MediaBrowser.Providers.Plugins.Omdb { private readonly IJsonSerializer _jsonSerializer; private readonly IHttpClient _httpClient; - private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; private readonly IFileSystem _fileSystem; private readonly IServerConfigurationManager _configurationManager; private readonly IApplicationHost _appHost; - public OmdbItemProvider(IJsonSerializer jsonSerializer, IApplicationHost appHost, IHttpClient httpClient, ILogger logger, ILibraryManager libraryManager, IFileSystem fileSystem, IServerConfigurationManager configurationManager) + public OmdbItemProvider( + IJsonSerializer jsonSerializer, + IApplicationHost appHost, + IHttpClient httpClient, + ILibraryManager libraryManager, + IFileSystem fileSystem, + IServerConfigurationManager configurationManager) { _jsonSerializer = jsonSerializer; _httpClient = httpClient; - _logger = logger; _libraryManager = libraryManager; _fileSystem = fileSystem; _configurationManager = configurationManager; _appHost = appHost; } + // After primary option public int Order => 2; @@ -80,7 +84,7 @@ namespace MediaBrowser.Providers.Plugins.Omdb var parsedName = _libraryManager.ParseName(name); var yearInName = parsedName.Year; name = parsedName.Name; - year = year ?? yearInName; + year ??= yearInName; } if (string.IsNullOrWhiteSpace(imdbId)) @@ -312,6 +316,5 @@ namespace MediaBrowser.Providers.Plugins.Omdb /// <value>The results.</value> public List<SearchResult> Search { get; set; } } - } } diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesProvider.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesProvider.cs index 7195dc42a..6e3c26c26 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesProvider.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesProvider.cs @@ -27,9 +27,6 @@ namespace MediaBrowser.Providers.Tmdb.TV public class TmdbSeriesProvider : IRemoteMetadataProvider<Series, SeriesInfo>, IHasOrder { private const string GetTvInfo3 = TmdbUtils.BaseTmdbApiUrl + @"3/tv/{0}?api_key={1}&append_to_response=credits,images,keywords,external_ids,videos,content_ratings"; - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - - internal static TmdbSeriesProvider Current { get; private set; } private readonly IJsonSerializer _jsonSerializer; private readonly IFileSystem _fileSystem; @@ -39,6 +36,10 @@ namespace MediaBrowser.Providers.Tmdb.TV private readonly IHttpClient _httpClient; private readonly ILibraryManager _libraryManager; + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + + internal static TmdbSeriesProvider Current { get; private set; } + public TmdbSeriesProvider( IJsonSerializer jsonSerializer, IFileSystem fileSystem, @@ -217,10 +218,9 @@ namespace MediaBrowser.Providers.Tmdb.TV var series = seriesResult.Item; series.Name = seriesInfo.Name; + series.OriginalTitle = seriesInfo.Original_Name; series.SetProviderId(MetadataProviders.Tmdb, seriesInfo.Id.ToString(_usCulture)); - //series.VoteCount = seriesInfo.vote_count; - string voteAvg = seriesInfo.Vote_Average.ToString(CultureInfo.InvariantCulture); if (float.TryParse(voteAvg, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out float rating)) @@ -240,7 +240,7 @@ namespace MediaBrowser.Providers.Tmdb.TV series.Genres = seriesInfo.Genres.Select(i => i.Name).ToArray(); } - //series.HomePageUrl = seriesInfo.homepage; + series.HomePageUrl = seriesInfo.Homepage; series.RunTimeTicks = seriesInfo.Episode_Run_Time.Select(i => TimeSpan.FromMinutes(i).Ticks).FirstOrDefault(); @@ -308,29 +308,61 @@ namespace MediaBrowser.Providers.Tmdb.TV seriesResult.ResetPeople(); var tmdbImageUrl = settings.images.GetImageUrl("original"); - if (seriesInfo.Credits != null && seriesInfo.Credits.Cast != null) + if (seriesInfo.Credits != null) { - foreach (var actor in seriesInfo.Credits.Cast.OrderBy(a => a.Order)) + if (seriesInfo.Credits.Cast != null) { - var personInfo = new PersonInfo + foreach (var actor in seriesInfo.Credits.Cast.OrderBy(a => a.Order)) { - Name = actor.Name.Trim(), - Role = actor.Character, - Type = PersonType.Actor, - SortOrder = actor.Order - }; + var personInfo = new PersonInfo + { + Name = actor.Name.Trim(), + Role = actor.Character, + Type = PersonType.Actor, + SortOrder = actor.Order + }; - if (!string.IsNullOrWhiteSpace(actor.Profile_Path)) - { - personInfo.ImageUrl = tmdbImageUrl + actor.Profile_Path; + if (!string.IsNullOrWhiteSpace(actor.Profile_Path)) + { + personInfo.ImageUrl = tmdbImageUrl + actor.Profile_Path; + } + + if (actor.Id > 0) + { + personInfo.SetProviderId(MetadataProviders.Tmdb, actor.Id.ToString(CultureInfo.InvariantCulture)); + } + + seriesResult.AddPerson(personInfo); } + } - if (actor.Id > 0) + if (seriesInfo.Credits.Crew != null) + { + var keepTypes = new[] { - personInfo.SetProviderId(MetadataProviders.Tmdb, actor.Id.ToString(CultureInfo.InvariantCulture)); - } + PersonType.Director, + PersonType.Writer, + PersonType.Producer + }; - seriesResult.AddPerson(personInfo); + foreach (var person in seriesInfo.Credits.Crew) + { + // Normalize this + var type = TmdbUtils.MapCrewToPersonType(person); + + if (!keepTypes.Contains(type, StringComparer.OrdinalIgnoreCase) + && !keepTypes.Contains(person.Job ?? string.Empty, StringComparer.OrdinalIgnoreCase)) + { + continue; + } + + seriesResult.AddPerson(new PersonInfo + { + Name = person.Name.Trim(), + Role = person.Job, + Type = type + }); + } } } } diff --git a/MediaBrowser.Providers/Tmdb/TmdbUtils.cs b/MediaBrowser.Providers/Tmdb/TmdbUtils.cs index 035b99c1a..7dacc7404 100644 --- a/MediaBrowser.Providers/Tmdb/TmdbUtils.cs +++ b/MediaBrowser.Providers/Tmdb/TmdbUtils.cs @@ -4,18 +4,51 @@ using MediaBrowser.Providers.Tmdb.Models.General; namespace MediaBrowser.Providers.Tmdb { + /// <summary> + /// Utilities for the TMDb provider + /// </summary> public static class TmdbUtils { + /// <summary> + /// URL of the TMDB instance to use. + /// </summary> public const string BaseTmdbUrl = "https://www.themoviedb.org/"; + + /// <summary> + /// URL of the TMDB API instance to use. + /// </summary> public const string BaseTmdbApiUrl = "https://api.themoviedb.org/"; + + /// <summary> + /// Name of the provider. + /// </summary> public const string ProviderName = "TheMovieDb"; + + /// <summary> + /// API key to use when performing an API call. + /// </summary> public const string ApiKey = "4219e299c89411838049ab0dab19ebd5"; + + /// <summary> + /// Value of the Accept header for requests to the provider. + /// </summary> public const string AcceptHeader = "application/json,image/*"; + /// <summary> + /// Maps the TMDB provided roles for crew members to Jellyfin roles. + /// </summary> + /// <param name="crew">Crew member to map against the Jellyfin person types.</param> + /// <returns>The Jellyfin person type.</returns> public static string MapCrewToPersonType(Crew crew) { if (crew.Department.Equals("production", StringComparison.InvariantCultureIgnoreCase) - && crew.Job.IndexOf("producer", StringComparison.InvariantCultureIgnoreCase) != -1) + && crew.Job.Contains("director", StringComparison.InvariantCultureIgnoreCase)) + { + return PersonType.Director; + } + + if (crew.Department.Equals("production", StringComparison.InvariantCultureIgnoreCase) + && crew.Job.Contains("producer", StringComparison.InvariantCultureIgnoreCase)) { return PersonType.Producer; } diff --git a/MediaBrowser.sln b/MediaBrowser.sln index 6a22fd02f..6b9fed83b 100644 --- a/MediaBrowser.sln +++ b/MediaBrowser.sln @@ -68,6 +68,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Jellyfin.Controller.Tests", EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Data", "Jellyfin.Data\Jellyfin.Data.csproj", "{F03299F2-469F-40EF-A655-3766F97A5702}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Jellyfin.Server.Implementations", "Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj", "{22C7DA3A-94F2-4E86-9CE6-86AB02B4F843}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MediaBrowser.Api.Tests", "tests\MediaBrowser.Api.Tests\MediaBrowser.Api.Tests.csproj", "{7C93C84F-105C-48E5-A878-406FA0A5B296}" EndProject Global @@ -184,6 +185,10 @@ Global {F03299F2-469F-40EF-A655-3766F97A5702}.Debug|Any CPU.Build.0 = Debug|Any CPU {F03299F2-469F-40EF-A655-3766F97A5702}.Release|Any CPU.ActiveCfg = Release|Any CPU {F03299F2-469F-40EF-A655-3766F97A5702}.Release|Any CPU.Build.0 = Release|Any CPU + {22C7DA3A-94F2-4E86-9CE6-86AB02B4F843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {22C7DA3A-94F2-4E86-9CE6-86AB02B4F843}.Debug|Any CPU.Build.0 = Debug|Any CPU + {22C7DA3A-94F2-4E86-9CE6-86AB02B4F843}.Release|Any CPU.ActiveCfg = Release|Any CPU + {22C7DA3A-94F2-4E86-9CE6-86AB02B4F843}.Release|Any CPU.Build.0 = Release|Any CPU {7C93C84F-105C-48E5-A878-406FA0A5B296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {7C93C84F-105C-48E5-A878-406FA0A5B296}.Debug|Any CPU.Build.0 = Debug|Any CPU {7C93C84F-105C-48E5-A878-406FA0A5B296}.Release|Any CPU.ActiveCfg = Release|Any CPU |
