aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrobibero <cody@robibe.ro>2020-09-01 18:27:55 -0600
committercrobibero <cody@robibe.ro>2020-09-01 18:27:55 -0600
commit65d05f92ac7f7e5398fa49d5a5fdf0d984ce6989 (patch)
treed2e301cc99576b0901eb33d3723e15c665e32e4b
parente97ccd87fb74c34222eccf03493a56144065eaa4 (diff)
parent506fc7cbaeb8f82716f84b125ac598ff740bf552 (diff)
Merge remote-tracking branch 'upstream/master' into dynamic-cors
-rw-r--r--CONTRIBUTORS.md1
-rw-r--r--Emby.Server.Implementations/ApplicationHost.cs18
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj4
-rw-r--r--Emby.Server.Implementations/Localization/Core/es_DO.json5
-rw-r--r--Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs285
-rw-r--r--Emby.Server.Implementations/Session/SessionManager.cs18
-rw-r--r--Jellyfin.Api/Controllers/ImageController.cs4
-rw-r--r--Jellyfin.Api/Controllers/ItemsController.cs6
-rw-r--r--Jellyfin.Api/Controllers/LibraryController.cs3
-rw-r--r--Jellyfin.Api/Controllers/LibraryStructureController.cs12
-rw-r--r--Jellyfin.Api/Controllers/MoviesController.cs3
-rw-r--r--Jellyfin.Api/Controllers/QuickConnectController.cs154
-rw-r--r--Jellyfin.Api/Controllers/UserController.cs34
-rw-r--r--Jellyfin.Api/Helpers/ProgressiveFileCopier.cs65
-rw-r--r--Jellyfin.Api/Models/LibraryStructureDto/AddVirtualFolderDto.cs (renamed from Jellyfin.Api/Models/LibraryStructureDto/LibraryOptionsDto.cs)6
-rw-r--r--Jellyfin.Api/Models/LibraryStructureDto/UpdateLibraryOptionsDto.cs21
-rw-r--r--Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs16
-rw-r--r--Jellyfin.Data/Entities/ActivityLog.cs3
-rw-r--r--Jellyfin.Data/Entities/Artwork.cs210
-rw-r--r--Jellyfin.Data/Entities/Book.cs72
-rw-r--r--Jellyfin.Data/Entities/BookMetadata.cs125
-rw-r--r--Jellyfin.Data/Entities/Chapter.cs277
-rw-r--r--Jellyfin.Data/Entities/Collection.cs123
-rw-r--r--Jellyfin.Data/Entities/CollectionItem.cs156
-rw-r--r--Jellyfin.Data/Entities/Company.cs159
-rw-r--r--Jellyfin.Data/Entities/CompanyMetadata.cs236
-rw-r--r--Jellyfin.Data/Entities/CustomItem.cs71
-rw-r--r--Jellyfin.Data/Entities/CustomItemMetadata.cs83
-rw-r--r--Jellyfin.Data/Entities/Episode.cs118
-rw-r--r--Jellyfin.Data/Entities/EpisodeMetadata.cs198
-rw-r--r--Jellyfin.Data/Entities/Genre.cs162
-rw-r--r--Jellyfin.Data/Entities/Group.cs3
-rw-r--r--Jellyfin.Data/Entities/Libraries/Artwork.cs81
-rw-r--r--Jellyfin.Data/Entities/Libraries/Book.cs28
-rw-r--r--Jellyfin.Data/Entities/Libraries/BookMetadata.cs55
-rw-r--r--Jellyfin.Data/Entities/Libraries/Chapter.cs102
-rw-r--r--Jellyfin.Data/Entities/Libraries/Collection.cs55
-rw-r--r--Jellyfin.Data/Entities/Libraries/CollectionItem.cs94
-rw-r--r--Jellyfin.Data/Entities/Libraries/Company.cs67
-rw-r--r--Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs74
-rw-r--r--Jellyfin.Data/Entities/Libraries/CustomItem.cs28
-rw-r--r--Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs36
-rw-r--r--Jellyfin.Data/Entities/Libraries/Episode.cs52
-rw-r--r--Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs67
-rw-r--r--Jellyfin.Data/Entities/Libraries/Genre.cs75
-rw-r--r--Jellyfin.Data/Entities/Libraries/Library.cs76
-rw-r--r--Jellyfin.Data/Entities/Libraries/LibraryItem.cs63
-rw-r--r--Jellyfin.Data/Entities/Libraries/MediaFile.cs94
-rw-r--r--Jellyfin.Data/Entities/Libraries/MediaFileStream.cs67
-rw-r--r--Jellyfin.Data/Entities/Libraries/Metadata.cs165
-rw-r--r--Jellyfin.Data/Entities/Libraries/MetadataProvider.cs67
-rw-r--r--Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs83
-rw-r--r--Jellyfin.Data/Entities/Libraries/Movie.cs28
-rw-r--r--Jellyfin.Data/Entities/Libraries/MovieMetadata.cs85
-rw-r--r--Jellyfin.Data/Entities/Libraries/MusicAlbum.cs29
-rw-r--r--Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs69
-rw-r--r--Jellyfin.Data/Entities/Libraries/Person.cs103
-rw-r--r--Jellyfin.Data/Entities/Libraries/PersonRole.cs98
-rw-r--r--Jellyfin.Data/Entities/Libraries/Photo.cs28
-rw-r--r--Jellyfin.Data/Entities/Libraries/PhotoMetadata.cs36
-rw-r--r--Jellyfin.Data/Entities/Libraries/Rating.cs78
-rw-r--r--Jellyfin.Data/Entities/Libraries/RatingSource.cs92
-rw-r--r--Jellyfin.Data/Entities/Libraries/Release.cs84
-rw-r--r--Jellyfin.Data/Entities/Libraries/Season.cs53
-rw-r--r--Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs47
-rw-r--r--Jellyfin.Data/Entities/Libraries/Series.cs46
-rw-r--r--Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs91
-rw-r--r--Jellyfin.Data/Entities/Libraries/Track.cs52
-rw-r--r--Jellyfin.Data/Entities/Libraries/TrackMetadata.cs36
-rw-r--r--Jellyfin.Data/Entities/Library.cs153
-rw-r--r--Jellyfin.Data/Entities/LibraryItem.cs175
-rw-r--r--Jellyfin.Data/Entities/LibraryRoot.cs199
-rw-r--r--Jellyfin.Data/Entities/MediaFile.cs212
-rw-r--r--Jellyfin.Data/Entities/MediaFileStream.cs155
-rw-r--r--Jellyfin.Data/Entities/Metadata.cs399
-rw-r--r--Jellyfin.Data/Entities/MetadataProvider.cs153
-rw-r--r--Jellyfin.Data/Entities/MetadataProviderId.cs201
-rw-r--r--Jellyfin.Data/Entities/Movie.cs72
-rw-r--r--Jellyfin.Data/Entities/MovieMetadata.cs244
-rw-r--r--Jellyfin.Data/Entities/MusicAlbum.cs71
-rw-r--r--Jellyfin.Data/Entities/MusicAlbumMetadata.cs207
-rw-r--r--Jellyfin.Data/Entities/Permission.cs3
-rw-r--r--Jellyfin.Data/Entities/Person.cs317
-rw-r--r--Jellyfin.Data/Entities/PersonRole.cs217
-rw-r--r--Jellyfin.Data/Entities/Photo.cs71
-rw-r--r--Jellyfin.Data/Entities/PhotoMetadata.cs84
-rw-r--r--Jellyfin.Data/Entities/Preference.cs3
-rw-r--r--Jellyfin.Data/Entities/Rating.cs194
-rw-r--r--Jellyfin.Data/Entities/RatingSource.cs239
-rw-r--r--Jellyfin.Data/Entities/Release.cs219
-rw-r--r--Jellyfin.Data/Entities/Season.cs119
-rw-r--r--Jellyfin.Data/Entities/SeasonMetadata.cs123
-rw-r--r--Jellyfin.Data/Entities/Series.cs165
-rw-r--r--Jellyfin.Data/Entities/SeriesMetadata.cs244
-rw-r--r--Jellyfin.Data/Entities/Track.cs120
-rw-r--r--Jellyfin.Data/Entities/TrackMetadata.cs83
-rw-r--r--Jellyfin.Data/Entities/User.cs3
-rw-r--r--Jellyfin.Data/ISavingChanges.cs9
-rw-r--r--Jellyfin.Data/Interfaces/IHasArtwork.cs16
-rw-r--r--Jellyfin.Data/Interfaces/IHasCompanies.cs16
-rw-r--r--Jellyfin.Data/Interfaces/IHasConcurrencyToken.cs18
-rw-r--r--Jellyfin.Data/Interfaces/IHasPermissions.cs (renamed from Jellyfin.Data/IHasPermissions.cs)0
-rw-r--r--Jellyfin.Data/Interfaces/IHasReleases.cs16
-rw-r--r--Jellyfin.Server.Implementations/JellyfinDb.cs4
-rw-r--r--Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs18
-rw-r--r--Jellyfin.Server/Startup.cs25
-rw-r--r--MediaBrowser.Common/IApplicationHost.cs7
-rw-r--r--MediaBrowser.Common/Json/Converters/JsonNullableStructConverter.cs44
-rw-r--r--MediaBrowser.Common/Json/JsonDefaults.cs6
-rw-r--r--MediaBrowser.Common/Net/DefaultHttpClientHandler.cs20
-rw-r--r--MediaBrowser.Common/Net/NamedClient.cs18
-rw-r--r--MediaBrowser.Controller/QuickConnect/IQuickConnect.cs87
-rw-r--r--MediaBrowser.Controller/Session/ISessionManager.cs8
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs6
-rw-r--r--MediaBrowser.Model/QuickConnect/QuickConnectResult.cs40
-rw-r--r--MediaBrowser.Model/QuickConnect/QuickConnectState.cs23
116 files changed, 3463 insertions, 6498 deletions
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index c5f35c088..1b4fdc8c4 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -16,6 +16,7 @@
- [bugfixin](https://github.com/bugfixin)
- [chaosinnovator](https://github.com/chaosinnovator)
- [ckcr4lyf](https://github.com/ckcr4lyf)
+ - [ConfusedPolarBear](https://github.com/ConfusedPolarBear)
- [crankdoofus](https://github.com/crankdoofus)
- [crobibero](https://github.com/crobibero)
- [cromefire](https://github.com/cromefire)
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index cb63cc85e..e9b063277 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -37,6 +37,7 @@ using Emby.Server.Implementations.LiveTv;
using Emby.Server.Implementations.Localization;
using Emby.Server.Implementations.Net;
using Emby.Server.Implementations.Playlists;
+using Emby.Server.Implementations.QuickConnect;
using Emby.Server.Implementations.ScheduledTasks;
using Emby.Server.Implementations.Security;
using Emby.Server.Implementations.Serialization;
@@ -71,6 +72,7 @@ using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Controller.QuickConnect;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Security;
using MediaBrowser.Controller.Session;
@@ -97,6 +99,7 @@ using MediaBrowser.Providers.Plugins.TheTvdb;
using MediaBrowser.Providers.Subtitles;
using MediaBrowser.XbmcMetadata.Providers;
using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Prometheus.DotNetRuntime;
@@ -626,6 +629,7 @@ namespace Emby.Server.Implementations
ServiceCollection.AddSingleton<ISessionContext, SessionContext>();
ServiceCollection.AddSingleton<IAuthService, AuthService>();
+ ServiceCollection.AddSingleton<IQuickConnect, QuickConnectManager>();
ServiceCollection.AddSingleton<ISubtitleEncoder, MediaBrowser.MediaEncoding.Subtitles.SubtitleEncoder>();
@@ -1393,6 +1397,20 @@ namespace Emby.Server.Implementations
_plugins = list.ToArray();
}
+ public IEnumerable<Assembly> GetApiPluginAssemblies()
+ {
+ var assemblies = _allConcreteTypes
+ .Where(i => typeof(ControllerBase).IsAssignableFrom(i))
+ .Select(i => i.Assembly)
+ .Distinct();
+
+ foreach (var assembly in assemblies)
+ {
+ Logger.LogDebug("Found API endpoints in plugin {name}", assembly.FullName);
+ yield return assembly;
+ }
+ }
+
public virtual void LaunchUrl(string url)
{
if (!CanLaunchWebBrowser)
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 60564f700..56fc57327 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -22,7 +22,7 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="IPNetwork2" Version="2.5.211" />
+ <PackageReference Include="IPNetwork2" Version="2.5.224" />
<PackageReference Include="Jellyfin.XmlTv" Version="10.6.2" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
@@ -37,7 +37,7 @@
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.6" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.6" />
<PackageReference Include="Mono.Nat" Version="2.0.2" />
- <PackageReference Include="prometheus-net.DotNetRuntime" Version="3.3.1" />
+ <PackageReference Include="prometheus-net.DotNetRuntime" Version="3.4.0" />
<PackageReference Include="ServiceStack.Text.Core" Version="5.9.2" />
<PackageReference Include="sharpcompress" Version="0.26.0" />
<PackageReference Include="SQLitePCL.pretty.netstandard" Version="2.1.0" />
diff --git a/Emby.Server.Implementations/Localization/Core/es_DO.json b/Emby.Server.Implementations/Localization/Core/es_DO.json
index 0ef16542f..26732eb3f 100644
--- a/Emby.Server.Implementations/Localization/Core/es_DO.json
+++ b/Emby.Server.Implementations/Localization/Core/es_DO.json
@@ -17,5 +17,8 @@
"Genres": "Géneros",
"Folders": "Carpetas",
"Favorites": "Favoritos",
- "FailedLoginAttemptWithUserName": "Intento de inicio de sesión fallido de {0}"
+ "FailedLoginAttemptWithUserName": "Intento de inicio de sesión fallido de {0}",
+ "HeaderFavoriteSongs": "Canciones Favoritas",
+ "HeaderFavoriteEpisodes": "Episodios Favoritos",
+ "HeaderFavoriteArtists": "Artistas Favoritos"
}
diff --git a/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
new file mode 100644
index 000000000..140a67541
--- /dev/null
+++ b/Emby.Server.Implementations/QuickConnect/QuickConnectManager.cs
@@ -0,0 +1,285 @@
+using System;
+using System.Collections.Concurrent;
+using System.Globalization;
+using System.Linq;
+using System.Security.Cryptography;
+using MediaBrowser.Common;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Authentication;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.QuickConnect;
+using MediaBrowser.Controller.Security;
+using MediaBrowser.Model.QuickConnect;
+using Microsoft.Extensions.Logging;
+
+namespace Emby.Server.Implementations.QuickConnect
+{
+ /// <summary>
+ /// Quick connect implementation.
+ /// </summary>
+ public class QuickConnectManager : IQuickConnect, IDisposable
+ {
+ private readonly RNGCryptoServiceProvider _rng = new RNGCryptoServiceProvider();
+ private readonly ConcurrentDictionary<string, QuickConnectResult> _currentRequests = new ConcurrentDictionary<string, QuickConnectResult>();
+
+ private readonly IServerConfigurationManager _config;
+ private readonly ILogger<QuickConnectManager> _logger;
+ private readonly IAuthenticationRepository _authenticationRepository;
+ private readonly IAuthorizationContext _authContext;
+ private readonly IServerApplicationHost _appHost;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="QuickConnectManager"/> class.
+ /// Should only be called at server startup when a singleton is created.
+ /// </summary>
+ /// <param name="config">Configuration.</param>
+ /// <param name="logger">Logger.</param>
+ /// <param name="appHost">Application host.</param>
+ /// <param name="authContext">Authentication context.</param>
+ /// <param name="authenticationRepository">Authentication repository.</param>
+ public QuickConnectManager(
+ IServerConfigurationManager config,
+ ILogger<QuickConnectManager> logger,
+ IServerApplicationHost appHost,
+ IAuthorizationContext authContext,
+ IAuthenticationRepository authenticationRepository)
+ {
+ _config = config;
+ _logger = logger;
+ _appHost = appHost;
+ _authContext = authContext;
+ _authenticationRepository = authenticationRepository;
+
+ ReloadConfiguration();
+ }
+
+ /// <inheritdoc/>
+ public int CodeLength { get; set; } = 6;
+
+ /// <inheritdoc/>
+ public string TokenName { get; set; } = "QuickConnect";
+
+ /// <inheritdoc/>
+ public QuickConnectState State { get; private set; } = QuickConnectState.Unavailable;
+
+ /// <inheritdoc/>
+ public int Timeout { get; set; } = 5;
+
+ private DateTime DateActivated { get; set; }
+
+ /// <inheritdoc/>
+ public void AssertActive()
+ {
+ if (State != QuickConnectState.Active)
+ {
+ throw new ArgumentException("Quick connect is not active on this server");
+ }
+ }
+
+ /// <inheritdoc/>
+ public void Activate()
+ {
+ DateActivated = DateTime.UtcNow;
+ SetState(QuickConnectState.Active);
+ }
+
+ /// <inheritdoc/>
+ public void SetState(QuickConnectState newState)
+ {
+ _logger.LogDebug("Changed quick connect state from {State} to {newState}", State, newState);
+
+ ExpireRequests(true);
+
+ State = newState;
+ _config.Configuration.QuickConnectAvailable = newState == QuickConnectState.Available || newState == QuickConnectState.Active;
+ _config.SaveConfiguration();
+
+ _logger.LogDebug("Configuration saved");
+ }
+
+ /// <inheritdoc/>
+ public QuickConnectResult TryConnect()
+ {
+ ExpireRequests();
+
+ if (State != QuickConnectState.Active)
+ {
+ _logger.LogDebug("Refusing quick connect initiation request, current state is {State}", State);
+ throw new AuthenticationException("Quick connect is not active on this server");
+ }
+
+ var code = GenerateCode();
+ var result = new QuickConnectResult()
+ {
+ Secret = GenerateSecureRandom(),
+ DateAdded = DateTime.UtcNow,
+ Code = code
+ };
+
+ _currentRequests[code] = result;
+ return result;
+ }
+
+ /// <inheritdoc/>
+ public QuickConnectResult CheckRequestStatus(string secret)
+ {
+ ExpireRequests();
+ AssertActive();
+
+ string code = _currentRequests.Where(x => x.Value.Secret == secret).Select(x => x.Value.Code).DefaultIfEmpty(string.Empty).First();
+
+ if (!_currentRequests.TryGetValue(code, out QuickConnectResult result))
+ {
+ throw new ResourceNotFoundException("Unable to find request with provided secret");
+ }
+
+ return result;
+ }
+
+ /// <inheritdoc/>
+ public string GenerateCode()
+ {
+ Span<byte> raw = stackalloc byte[4];
+
+ int min = (int)Math.Pow(10, CodeLength - 1);
+ int max = (int)Math.Pow(10, CodeLength);
+
+ uint scale = uint.MaxValue;
+ while (scale == uint.MaxValue)
+ {
+ _rng.GetBytes(raw);
+ scale = BitConverter.ToUInt32(raw);
+ }
+
+ int code = (int)(min + ((max - min) * (scale / (double)uint.MaxValue)));
+ return code.ToString(CultureInfo.InvariantCulture);
+ }
+
+ /// <inheritdoc/>
+ public bool AuthorizeRequest(Guid userId, string code)
+ {
+ ExpireRequests();
+ AssertActive();
+
+ if (!_currentRequests.TryGetValue(code, out QuickConnectResult result))
+ {
+ throw new ResourceNotFoundException("Unable to find request");
+ }
+
+ if (result.Authenticated)
+ {
+ throw new InvalidOperationException("Request is already authorized");
+ }
+
+ result.Authentication = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
+
+ // Change the time on the request so it expires one minute into the future. It can't expire immediately as otherwise some clients wouldn't ever see that they have been authenticated.
+ var added = result.DateAdded ?? DateTime.UtcNow.Subtract(TimeSpan.FromMinutes(Timeout));
+ result.DateAdded = added.Subtract(TimeSpan.FromMinutes(Timeout - 1));
+
+ _authenticationRepository.Create(new AuthenticationInfo
+ {
+ AppName = TokenName,
+ AccessToken = result.Authentication,
+ DateCreated = DateTime.UtcNow,
+ DeviceId = _appHost.SystemId,
+ DeviceName = _appHost.FriendlyName,
+ AppVersion = _appHost.ApplicationVersionString,
+ UserId = userId
+ });
+
+ _logger.LogDebug("Authorizing device with code {Code} to login as user {userId}", code, userId);
+
+ return true;
+ }
+
+ /// <inheritdoc/>
+ public int DeleteAllDevices(Guid user)
+ {
+ var raw = _authenticationRepository.Get(new AuthenticationInfoQuery()
+ {
+ DeviceId = _appHost.SystemId,
+ UserId = user
+ });
+
+ var tokens = raw.Items.Where(x => x.AppName.StartsWith(TokenName, StringComparison.Ordinal));
+
+ var removed = 0;
+ foreach (var token in tokens)
+ {
+ _authenticationRepository.Delete(token);
+ _logger.LogDebug("Deleted token {AccessToken}", token.AccessToken);
+ removed++;
+ }
+
+ return removed;
+ }
+
+ /// <summary>
+ /// Dispose.
+ /// </summary>
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ /// <summary>
+ /// Dispose.
+ /// </summary>
+ /// <param name="disposing">Dispose unmanaged resources.</param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _rng?.Dispose();
+ }
+ }
+
+ private string GenerateSecureRandom(int length = 32)
+ {
+ Span<byte> bytes = stackalloc byte[length];
+ _rng.GetBytes(bytes);
+
+ return Hex.Encode(bytes);
+ }
+
+ /// <inheritdoc/>
+ public void ExpireRequests(bool expireAll = false)
+ {
+ // Check if quick connect should be deactivated
+ if (State == QuickConnectState.Active && DateTime.UtcNow > DateActivated.AddMinutes(Timeout) && !expireAll)
+ {
+ _logger.LogDebug("Quick connect time expired, deactivating");
+ SetState(QuickConnectState.Available);
+ expireAll = true;
+ }
+
+ // Expire stale connection requests
+ var code = string.Empty;
+ var values = _currentRequests.Values.ToList();
+
+ for (int i = 0; i < values.Count; i++)
+ {
+ var added = values[i].DateAdded ?? DateTime.UnixEpoch;
+ if (DateTime.UtcNow > added.AddMinutes(Timeout) || expireAll)
+ {
+ code = values[i].Code;
+ _logger.LogDebug("Removing expired request {code}", code);
+
+ if (!_currentRequests.TryRemove(code, out _))
+ {
+ _logger.LogWarning("Request {code} already expired", code);
+ }
+ }
+ }
+ }
+
+ private void ReloadConfiguration()
+ {
+ State = _config.Configuration.QuickConnectAvailable ? QuickConnectState.Available : QuickConnectState.Unavailable;
+ }
+ }
+}
diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs
index dad414142..ca8e0e29b 100644
--- a/Emby.Server.Implementations/Session/SessionManager.cs
+++ b/Emby.Server.Implementations/Session/SessionManager.cs
@@ -1429,6 +1429,24 @@ namespace Emby.Server.Implementations.Session
return AuthenticateNewSessionInternal(request, false);
}
+ public Task<AuthenticationResult> AuthenticateQuickConnect(AuthenticationRequest request, string token)
+ {
+ var result = _authRepo.Get(new AuthenticationInfoQuery()
+ {
+ AccessToken = token,
+ DeviceId = _appHost.SystemId,
+ Limit = 1
+ });
+
+ if (result.TotalRecordCount == 0)
+ {
+ throw new SecurityException("Unknown quick connect token");
+ }
+
+ request.UserId = result.Items[0].UserId;
+ return AuthenticateNewSessionInternal(request, false);
+ }
+
private async Task<AuthenticationResult> AuthenticateNewSessionInternal(AuthenticationRequest request, bool enforcePassword)
{
CheckDisposed();
diff --git a/Jellyfin.Api/Controllers/ImageController.cs b/Jellyfin.Api/Controllers/ImageController.cs
index ca9c2fa46..a204fe35c 100644
--- a/Jellyfin.Api/Controllers/ImageController.cs
+++ b/Jellyfin.Api/Controllers/ImageController.cs
@@ -1281,9 +1281,9 @@ namespace Jellyfin.Api.Controllers
Response.Headers.Add(HeaderNames.LastModified, dateImageModified.ToUniversalTime().ToString("ddd, dd MMM yyyy HH:mm:ss \"GMT\"", new CultureInfo("en-US", false)));
// if the image was not modified since "ifModifiedSinceHeader"-header, return a HTTP status code 304 not modified
- if (!(dateImageModified > ifModifiedSinceHeader))
+ if (!(dateImageModified > ifModifiedSinceHeader) && cacheDuration.HasValue)
{
- if (ifModifiedSinceHeader.Add(cacheDuration!.Value) < DateTime.UtcNow)
+ if (ifModifiedSinceHeader.Add(cacheDuration.Value) < DateTime.UtcNow)
{
Response.StatusCode = StatusCodes.Status304NotModified;
return new ContentResult();
diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs
index 1b8b68313..f9273bad6 100644
--- a/Jellyfin.Api/Controllers/ItemsController.cs
+++ b/Jellyfin.Api/Controllers/ItemsController.cs
@@ -4,10 +4,10 @@ using System.Linq;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
-using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
@@ -266,7 +266,9 @@ namespace Jellyfin.Api.Controllers
bool isInEnabledFolder = user!.GetPreference(PreferenceKind.EnabledFolders).Any(i => new Guid(i) == item.Id)
// Assume all folders inside an EnabledChannel are enabled
- || user.GetPreference(PreferenceKind.EnabledChannels).Any(i => new Guid(i) == item.Id);
+ || user.GetPreference(PreferenceKind.EnabledChannels).Any(i => new Guid(i) == item.Id)
+ // Assume all items inside an EnabledChannel are enabled
+ || user.GetPreference(PreferenceKind.EnabledChannels).Any(i => new Guid(i) == item.ChannelId);
var collectionFolders = _libraryManager.GetCollectionFolders(item);
foreach (var collectionFolder in collectionFolders)
diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs
index 796d2d8aa..a30873e9e 100644
--- a/Jellyfin.Api/Controllers/LibraryController.cs
+++ b/Jellyfin.Api/Controllers/LibraryController.cs
@@ -19,6 +19,7 @@ using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Net;
@@ -35,8 +36,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Book = MediaBrowser.Controller.Entities.Book;
-using Movie = Jellyfin.Data.Entities.Movie;
-using MusicAlbum = Jellyfin.Data.Entities.MusicAlbum;
namespace Jellyfin.Api.Controllers
{
diff --git a/Jellyfin.Api/Controllers/LibraryStructureController.cs b/Jellyfin.Api/Controllers/LibraryStructureController.cs
index cdab4f356..d290e3c5b 100644
--- a/Jellyfin.Api/Controllers/LibraryStructureController.cs
+++ b/Jellyfin.Api/Controllers/LibraryStructureController.cs
@@ -76,7 +76,7 @@ namespace Jellyfin.Api.Controllers
[FromQuery] string? name,
[FromQuery] string? collectionType,
[FromQuery] string[] paths,
- [FromBody] LibraryOptionsDto? libraryOptionsDto,
+ [FromBody] AddVirtualFolderDto? libraryOptionsDto,
[FromQuery] bool refreshLibrary = false)
{
var libraryOptions = libraryOptionsDto?.LibraryOptions ?? new LibraryOptions();
@@ -312,19 +312,17 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// Update library options.
/// </summary>
- /// <param name="id">The library name.</param>
- /// <param name="libraryOptions">The library options.</param>
+ /// <param name="request">The library name and options.</param>
/// <response code="204">Library updated.</response>
/// <returns>A <see cref="NoContentResult"/>.</returns>
[HttpPost("LibraryOptions")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult UpdateLibraryOptions(
- [FromQuery] string? id,
- [FromBody] LibraryOptions? libraryOptions)
+ [FromBody] UpdateLibraryOptionsDto request)
{
- var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(id);
+ var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(request.Id);
- collectionFolder.UpdateLibraryOptions(libraryOptions);
+ collectionFolder.UpdateLibraryOptions(request.LibraryOptions);
return NoContent();
}
}
diff --git a/Jellyfin.Api/Controllers/MoviesController.cs b/Jellyfin.Api/Controllers/MoviesController.cs
index 148d8a18e..7fcfc749d 100644
--- a/Jellyfin.Api/Controllers/MoviesController.cs
+++ b/Jellyfin.Api/Controllers/MoviesController.cs
@@ -10,6 +10,7 @@ using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Dto;
@@ -181,7 +182,7 @@ namespace Jellyfin.Api.Controllers
DtoOptions dtoOptions,
RecommendationType type)
{
- var itemTypes = new List<string> { nameof(MediaBrowser.Controller.Entities.Movies.Movie) };
+ var itemTypes = new List<string> { nameof(Movie) };
if (_serverConfigurationManager.Configuration.EnableExternalContentInSuggestions)
{
itemTypes.Add(nameof(Trailer));
diff --git a/Jellyfin.Api/Controllers/QuickConnectController.cs b/Jellyfin.Api/Controllers/QuickConnectController.cs
new file mode 100644
index 000000000..73da2f906
--- /dev/null
+++ b/Jellyfin.Api/Controllers/QuickConnectController.cs
@@ -0,0 +1,154 @@
+using System.ComponentModel.DataAnnotations;
+using Jellyfin.Api.Constants;
+using Jellyfin.Api.Helpers;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.QuickConnect;
+using MediaBrowser.Model.QuickConnect;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Jellyfin.Api.Controllers
+{
+ /// <summary>
+ /// Quick connect controller.
+ /// </summary>
+ public class QuickConnectController : BaseJellyfinApiController
+ {
+ private readonly IQuickConnect _quickConnect;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="QuickConnectController"/> class.
+ /// </summary>
+ /// <param name="quickConnect">Instance of the <see cref="IQuickConnect"/> interface.</param>
+ public QuickConnectController(IQuickConnect quickConnect)
+ {
+ _quickConnect = quickConnect;
+ }
+
+ /// <summary>
+ /// Gets the current quick connect state.
+ /// </summary>
+ /// <response code="200">Quick connect state returned.</response>
+ /// <returns>The current <see cref="QuickConnectState"/>.</returns>
+ [HttpGet("Status")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult<QuickConnectState> GetStatus()
+ {
+ _quickConnect.ExpireRequests();
+ return _quickConnect.State;
+ }
+
+ /// <summary>
+ /// Initiate a new quick connect request.
+ /// </summary>
+ /// <response code="200">Quick connect request successfully created.</response>
+ /// <response code="401">Quick connect is not active on this server.</response>
+ /// <returns>A <see cref="QuickConnectResult"/> with a secret and code for future use or an error message.</returns>
+ [HttpGet("Initiate")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult<QuickConnectResult> Initiate()
+ {
+ return _quickConnect.TryConnect();
+ }
+
+ /// <summary>
+ /// Attempts to retrieve authentication information.
+ /// </summary>
+ /// <param name="secret">Secret previously returned from the Initiate endpoint.</param>
+ /// <response code="200">Quick connect result returned.</response>
+ /// <response code="404">Unknown quick connect secret.</response>
+ /// <returns>An updated <see cref="QuickConnectResult"/>.</returns>
+ [HttpGet("Connect")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ public ActionResult<QuickConnectResult> Connect([FromQuery, Required] string secret)
+ {
+ try
+ {
+ return _quickConnect.CheckRequestStatus(secret);
+ }
+ catch (ResourceNotFoundException)
+ {
+ return NotFound("Unknown secret");
+ }
+ }
+
+ /// <summary>
+ /// Temporarily activates quick connect for five minutes.
+ /// </summary>
+ /// <response code="204">Quick connect has been temporarily activated.</response>
+ /// <response code="403">Quick connect is unavailable on this server.</response>
+ /// <returns>An <see cref="NoContentResult"/> on success.</returns>
+ [HttpPost("Activate")]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public ActionResult Activate()
+ {
+ if (_quickConnect.State == QuickConnectState.Unavailable)
+ {
+ return Forbid("Quick connect is unavailable");
+ }
+
+ _quickConnect.Activate();
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Enables or disables quick connect.
+ /// </summary>
+ /// <param name="status">New <see cref="QuickConnectState"/>.</param>
+ /// <response code="204">Quick connect state set successfully.</response>
+ /// <returns>An <see cref="NoContentResult"/> on success.</returns>
+ [HttpPost("Available")]
+ [Authorize(Policy = Policies.RequiresElevation)]
+ [ProducesResponseType(StatusCodes.Status204NoContent)]
+ public ActionResult Available([FromQuery] QuickConnectState status = QuickConnectState.Available)
+ {
+ _quickConnect.SetState(status);
+ return NoContent();
+ }
+
+ /// <summary>
+ /// Authorizes a pending quick connect request.
+ /// </summary>
+ /// <param name="code">Quick connect code to authorize.</param>
+ /// <response code="200">Quick connect result authorized successfully.</response>
+ /// <response code="403">Unknown user id.</response>
+ /// <returns>Boolean indicating if the authorization was successful.</returns>
+ [HttpPost("Authorize")]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public ActionResult<bool> Authorize([FromQuery, Required] string code)
+ {
+ var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
+ if (!userId.HasValue)
+ {
+ return Forbid("Unknown user id");
+ }
+
+ return _quickConnect.AuthorizeRequest(userId.Value, code);
+ }
+
+ /// <summary>
+ /// Deauthorize all quick connect devices for the current user.
+ /// </summary>
+ /// <response code="200">All quick connect devices were deleted.</response>
+ /// <returns>The number of devices that were deleted.</returns>
+ [HttpPost("Deauthorize")]
+ [Authorize(Policy = Policies.DefaultAuthorization)]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public ActionResult<int> Deauthorize()
+ {
+ var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
+ if (!userId.HasValue)
+ {
+ return 0;
+ }
+
+ return _quickConnect.DeleteAllDevices(userId.Value);
+ }
+ }
+}
diff --git a/Jellyfin.Api/Controllers/UserController.cs b/Jellyfin.Api/Controllers/UserController.cs
index 272312522..d67f82219 100644
--- a/Jellyfin.Api/Controllers/UserController.cs
+++ b/Jellyfin.Api/Controllers/UserController.cs
@@ -217,6 +217,40 @@ namespace Jellyfin.Api.Controllers
}
/// <summary>
+ /// Authenticates a user with quick connect.
+ /// </summary>
+ /// <param name="request">The <see cref="QuickConnectDto"/> request.</param>
+ /// <response code="200">User authenticated.</response>
+ /// <response code="400">Missing token.</response>
+ /// <returns>A <see cref="Task"/> containing an <see cref="AuthenticationRequest"/> with information about the new session.</returns>
+ [HttpPost("AuthenticateWithQuickConnect")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ public async Task<ActionResult<AuthenticationResult>> AuthenticateWithQuickConnect([FromBody, Required] QuickConnectDto request)
+ {
+ var auth = _authContext.GetAuthorizationInfo(Request);
+
+ try
+ {
+ var authRequest = new AuthenticationRequest
+ {
+ App = auth.Client,
+ AppVersion = auth.Version,
+ DeviceId = auth.DeviceId,
+ DeviceName = auth.Device,
+ };
+
+ return await _sessionManager.AuthenticateQuickConnect(
+ authRequest,
+ request.Token).ConfigureAwait(false);
+ }
+ catch (SecurityException e)
+ {
+ // rethrow adding IP address to message
+ throw new SecurityException($"[{HttpContext.Connection.RemoteIpAddress}] {e.Message}", e);
+ }
+ }
+
+ /// <summary>
/// Updates a user's password.
/// </summary>
/// <param name="userId">The user id.</param>
diff --git a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
index 432df9708..e00ed3304 100644
--- a/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
+++ b/Jellyfin.Api/Helpers/ProgressiveFileCopier.cs
@@ -130,34 +130,10 @@ namespace Jellyfin.Api.Helpers
private async Task<int> CopyToInternalAsync(Stream source, Stream destination, bool readAsync, CancellationToken cancellationToken)
{
var array = ArrayPool<byte>.Shared.Rent(IODefaults.CopyToBufferSize);
- int bytesRead;
- int totalBytesRead = 0;
-
- if (readAsync)
- {
- bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false);
- }
- else
- {
- bytesRead = source.Read(array, 0, array.Length);
- }
-
- while (bytesRead != 0)
+ try
{
- var bytesToWrite = bytesRead;
-
- if (bytesToWrite > 0)
- {
- await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false);
-
- _bytesWritten += bytesRead;
- totalBytesRead += bytesRead;
-
- if (_job != null)
- {
- _job.BytesDownloaded = Math.Max(_job.BytesDownloaded ?? _bytesWritten, _bytesWritten);
- }
- }
+ int bytesRead;
+ int totalBytesRead = 0;
if (readAsync)
{
@@ -167,9 +143,40 @@ namespace Jellyfin.Api.Helpers
{
bytesRead = source.Read(array, 0, array.Length);
}
- }
- return totalBytesRead;
+ while (bytesRead != 0)
+ {
+ var bytesToWrite = bytesRead;
+
+ if (bytesToWrite > 0)
+ {
+ await destination.WriteAsync(array, 0, Convert.ToInt32(bytesToWrite), cancellationToken).ConfigureAwait(false);
+
+ _bytesWritten += bytesRead;
+ totalBytesRead += bytesRead;
+
+ if (_job != null)
+ {
+ _job.BytesDownloaded = Math.Max(_job.BytesDownloaded ?? _bytesWritten, _bytesWritten);
+ }
+ }
+
+ if (readAsync)
+ {
+ bytesRead = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false);
+ }
+ else
+ {
+ bytesRead = source.Read(array, 0, array.Length);
+ }
+ }
+
+ return totalBytesRead;
+ }
+ finally
+ {
+ ArrayPool<byte>.Shared.Return(array);
+ }
}
}
}
diff --git a/Jellyfin.Api/Models/LibraryStructureDto/LibraryOptionsDto.cs b/Jellyfin.Api/Models/LibraryStructureDto/AddVirtualFolderDto.cs
index a13cb90db..ab68d5223 100644
--- a/Jellyfin.Api/Models/LibraryStructureDto/LibraryOptionsDto.cs
+++ b/Jellyfin.Api/Models/LibraryStructureDto/AddVirtualFolderDto.cs
@@ -3,13 +3,13 @@
namespace Jellyfin.Api.Models.LibraryStructureDto
{
/// <summary>
- /// Library options dto.
+ /// Add virtual folder dto.
/// </summary>
- public class LibraryOptionsDto
+ public class AddVirtualFolderDto
{
/// <summary>
/// Gets or sets library options.
/// </summary>
public LibraryOptions? LibraryOptions { get; set; }
}
-} \ No newline at end of file
+}
diff --git a/Jellyfin.Api/Models/LibraryStructureDto/UpdateLibraryOptionsDto.cs b/Jellyfin.Api/Models/LibraryStructureDto/UpdateLibraryOptionsDto.cs
new file mode 100644
index 000000000..c78ed51f7
--- /dev/null
+++ b/Jellyfin.Api/Models/LibraryStructureDto/UpdateLibraryOptionsDto.cs
@@ -0,0 +1,21 @@
+using System;
+using MediaBrowser.Model.Configuration;
+
+namespace Jellyfin.Api.Models.LibraryStructureDto
+{
+ /// <summary>
+ /// Update library options dto.
+ /// </summary>
+ public class UpdateLibraryOptionsDto
+ {
+ /// <summary>
+ /// Gets or sets the library item id.
+ /// </summary>
+ public Guid Id { get; set; }
+
+ /// <summary>
+ /// Gets or sets library options.
+ /// </summary>
+ public LibraryOptions? LibraryOptions { get; set; }
+ }
+}
diff --git a/Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs b/Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs
new file mode 100644
index 000000000..c3a2d5cec
--- /dev/null
+++ b/Jellyfin.Api/Models/UserDtos/QuickConnectDto.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace Jellyfin.Api.Models.UserDtos
+{
+ /// <summary>
+ /// The quick connect request body.
+ /// </summary>
+ public class QuickConnectDto
+ {
+ /// <summary>
+ /// Gets or sets the quick connect token.
+ /// </summary>
+ [Required]
+ public string? Token { get; set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/ActivityLog.cs b/Jellyfin.Data/Entities/ActivityLog.cs
index ac61b9e3b..3858916d1 100644
--- a/Jellyfin.Data/Entities/ActivityLog.cs
+++ b/Jellyfin.Data/Entities/ActivityLog.cs
@@ -3,6 +3,7 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Data.Entities
@@ -10,7 +11,7 @@ namespace Jellyfin.Data.Entities
/// <summary>
/// An entity referencing an activity log entry.
/// </summary>
- public partial class ActivityLog : ISavingChanges
+ public partial class ActivityLog : IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="ActivityLog"/> class.
diff --git a/Jellyfin.Data/Entities/Artwork.cs b/Jellyfin.Data/Entities/Artwork.cs
deleted file mode 100644
index 4508f5488..000000000
--- a/Jellyfin.Data/Entities/Artwork.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-
-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, 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
- {
- string oldValue = _Path;
- SetPath(oldValue, ref value);
- if (oldValue != value)
- {
- _Path = 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
- {
- Enums.ArtKind value = _Kind;
- GetKind(ref value);
- return _Kind = value;
- }
-
- set
- {
- Enums.ArtKind oldValue = _Kind;
- SetKind(oldValue, ref value);
- if (oldValue != value)
- {
- _Kind = value;
- }
- }
- }
-
- /// <summary>
- /// Required, ConcurrenyToken.
- /// </summary>
- [ConcurrencyCheck]
- [Required]
- public uint RowVersion { get; set; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Book.cs b/Jellyfin.Data/Entities/Book.cs
deleted file mode 100644
index b6198ee01..000000000
--- a/Jellyfin.Data/Entities/Book.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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()
- {
- BookMetadata = new HashSet<BookMetadata>();
- Releases = new HashSet<Release>();
-
- 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>
- /// 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="dateadded">The date the object was added.</param>
- public Book(Guid urlid, DateTime dateadded)
- {
- this.UrlId = urlid;
-
- this.BookMetadata = new HashSet<BookMetadata>();
- this.Releases = new HashSet<Release>();
-
- 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="dateadded">The date the object was added.</param>
- public static Book Create(Guid urlid, DateTime dateadded)
- {
- return new Book(urlid, dateadded);
- }
-
- /*************************************************************************
- * Properties
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- [ForeignKey("BookMetadata_BookMetadata_Id")]
- public virtual ICollection<BookMetadata> BookMetadata { 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
deleted file mode 100644
index 9734cf20e..000000000
--- a/Jellyfin.Data/Entities/BookMetadata.cs
+++ /dev/null
@@ -1,125 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- long? oldValue = _ISBN;
- SetISBN(oldValue, ref value);
- if (oldValue != value)
- {
- _ISBN = value;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- [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
deleted file mode 100644
index 52cdeef78..000000000
--- a/Jellyfin.Data/Entities/Chapter.cs
+++ /dev/null
@@ -1,277 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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>
- /// 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, Release _release0)
- {
- if (string.IsNullOrEmpty(language))
- {
- throw new ArgumentNullException(nameof(language));
- }
-
- this.Language = language;
-
- this.TimeStart = timestart;
-
- if (_release0 == null)
- {
- throw new ArgumentNullException(nameof(_release0));
- }
-
- _release0.Chapters.Add(this);
-
-
- 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, Release _release0)
- {
- return new Chapter(language, timestart, _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 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)
- {
- _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>
- /// 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)
- {
- _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>
- /// 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)
- {
- _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);
-
- public long? TimeEnd
- {
- get
- {
- 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; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Collection.cs b/Jellyfin.Data/Entities/Collection.cs
deleted file mode 100644
index 0c317d71e..000000000
--- a/Jellyfin.Data/Entities/Collection.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-#pragma warning disable CS1591
-
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- public partial class Collection
- {
- partial void Init();
-
- /// <summary>
- /// Default constructor.
- /// </summary>
- public Collection()
- {
- CollectionItem = new LinkedList<CollectionItem>();
-
- 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 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)
- {
- _Name = value;
- }
- }
- }
-
- /// <summary>
- /// Required, ConcurrenyToken.
- /// </summary>
- [ConcurrencyCheck]
- [Required]
- public uint RowVersion { get; set; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * 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
deleted file mode 100644
index fb589c2ba..000000000
--- a/Jellyfin.Data/Entities/CollectionItem.cs
+++ /dev/null
@@ -1,156 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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(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
- {
- 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
- *************************************************************************/
-
- /// <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
deleted file mode 100644
index 8bd48045d..000000000
--- a/Jellyfin.Data/Entities/Company.cs
+++ /dev/null
@@ -1,159 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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 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
- {
- int value = _Id;
- GetId(ref value);
- return _Id = value;
- }
-
- 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
deleted file mode 100644
index 48ea4bdc5..000000000
--- a/Jellyfin.Data/Entities/CompanyMetadata.cs
+++ /dev/null
@@ -1,236 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- string value = _Country;
- GetCountry(ref value);
- return _Country = value;
- }
-
- set
- {
- string oldValue = _Country;
- SetCountry(oldValue, ref value);
- if (oldValue != value)
- {
- _Country = 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)
- {
- _Homepage = value;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/CustomItem.cs b/Jellyfin.Data/Entities/CustomItem.cs
deleted file mode 100644
index 8ea08488f..000000000
--- a/Jellyfin.Data/Entities/CustomItem.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- public partial class CustomItem : LibraryItem
- {
- partial void 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>();
-
- Init();
- }
-
- /// <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();
- }
-
- /// <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="dateadded">The date the object was added.</param>
- public CustomItem(Guid urlid, DateTime dateadded)
- {
- this.UrlId = urlid;
-
- this.CustomItemMetadata = new HashSet<CustomItemMetadata>();
- this.Releases = new HashSet<Release>();
-
- 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="dateadded">The date the object was added.</param>
- public static CustomItem Create(Guid urlid, DateTime dateadded)
- {
- return new CustomItem(urlid, dateadded);
- }
-
- /*************************************************************************
- * Properties
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- [ForeignKey("CustomItemMetadata_CustomItemMetadata_Id")]
- public virtual ICollection<CustomItemMetadata> CustomItemMetadata { 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
deleted file mode 100644
index 9c89399e6..000000000
--- a/Jellyfin.Data/Entities/CustomItemMetadata.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-
-namespace Jellyfin.Data.Entities
-{
- 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()
- {
- 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>
- /// 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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 (_customitem0 == null)
- {
- throw new ArgumentNullException(nameof(_customitem0));
- }
-
- _customitem0.CustomItemMetadata.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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Episode.cs b/Jellyfin.Data/Entities/Episode.cs
deleted file mode 100644
index 1c1894448..000000000
--- a/Jellyfin.Data/Entities/Episode.cs
+++ /dev/null
@@ -1,118 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</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="dateadded">The date the object was added.</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
- {
- int? value = _EpisodeNumber;
- GetEpisodeNumber(ref value);
- return _EpisodeNumber = value;
- }
-
- set
- {
- int? oldValue = _EpisodeNumber;
- SetEpisodeNumber(oldValue, ref value);
- if (oldValue != value)
- {
- _EpisodeNumber = value;
- }
- }
- }
-
- /*************************************************************************
- * 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
deleted file mode 100644
index 26ad7200b..000000000
--- a/Jellyfin.Data/Entities/EpisodeMetadata.cs
+++ /dev/null
@@ -1,198 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- string oldValue = _Plot;
- SetPlot(oldValue, ref value);
- if (oldValue != value)
- {
- _Plot = 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)
- {
- _Tagline = value;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Genre.cs b/Jellyfin.Data/Entities/Genre.cs
deleted file mode 100644
index 43a180f6b..000000000
--- a/Jellyfin.Data/Entities/Genre.cs
+++ /dev/null
@@ -1,162 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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, 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
- {
- 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)
- {
- _Name = value;
- }
- }
- }
-
- /// <summary>
- /// Required, ConcurrenyToken.
- /// </summary>
- [ConcurrencyCheck]
- [Required]
- public uint RowVersion { get; set; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Group.cs b/Jellyfin.Data/Entities/Group.cs
index a1ec6b1fa..ca12ba421 100644
--- a/Jellyfin.Data/Entities/Group.cs
+++ b/Jellyfin.Data/Entities/Group.cs
@@ -6,13 +6,14 @@ using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Interfaces;
namespace Jellyfin.Data.Entities
{
/// <summary>
/// An entity representing a group.
/// </summary>
- public partial class Group : IHasPermissions, ISavingChanges
+ public partial class Group : IHasPermissions, IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="Group"/> class.
diff --git a/Jellyfin.Data/Entities/Libraries/Artwork.cs b/Jellyfin.Data/Entities/Libraries/Artwork.cs
new file mode 100644
index 000000000..7be22af25
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Artwork.cs
@@ -0,0 +1,81 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Enums;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing artwork.
+ /// </summary>
+ public class Artwork : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Artwork"/> class.
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="kind">The kind of art.</param>
+ /// <param name="owner">The owner.</param>
+ public Artwork(string path, ArtKind kind, IHasArtwork owner)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ Path = path;
+ Kind = kind;
+
+ owner?.Artwork.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Artwork"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Artwork()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the path.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 65535.
+ /// </remarks>
+ [Required]
+ [MaxLength(65535)]
+ [StringLength(65535)]
+ public string Path { get; set; }
+
+ /// <summary>
+ /// Gets or sets the kind of artwork.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public ArtKind Kind { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Book.cs b/Jellyfin.Data/Entities/Libraries/Book.cs
new file mode 100644
index 000000000..8337788dd
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Book.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a book.
+ /// </summary>
+ public class Book : LibraryItem, IHasReleases
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Book"/> class.
+ /// </summary>
+ public Book()
+ {
+ BookMetadata = new HashSet<BookMetadata>();
+ Releases = new HashSet<Release>();
+ }
+
+ /// <summary>
+ /// Gets or sets a collection containing the metadata for this book.
+ /// </summary>
+ public virtual ICollection<BookMetadata> BookMetadata { get; protected set; }
+
+ /// <inheritdoc />
+ public virtual ICollection<Release> Releases { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/BookMetadata.cs b/Jellyfin.Data/Entities/Libraries/BookMetadata.cs
new file mode 100644
index 000000000..bd716712b
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/BookMetadata.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity containing metadata for a book.
+ /// </summary>
+ public class BookMetadata : Metadata, IHasCompanies
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BookMetadata"/> class.
+ /// </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="book">The book.</param>
+ public BookMetadata(string title, string language, Book book) : base(title, language)
+ {
+ if (book == null)
+ {
+ throw new ArgumentNullException(nameof(book));
+ }
+
+ book.BookMetadata.Add(this);
+
+ Publishers = new HashSet<Company>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="BookMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected BookMetadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the ISBN.
+ /// </summary>
+ public long? Isbn { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection of the publishers for this book.
+ /// </summary>
+ public virtual ICollection<Company> Publishers { get; protected set; }
+
+ /// <inheritdoc />
+ [NotMapped]
+ public ICollection<Company> Companies => Publishers;
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Chapter.cs b/Jellyfin.Data/Entities/Libraries/Chapter.cs
new file mode 100644
index 000000000..d9293c3cc
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Chapter.cs
@@ -0,0 +1,102 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a chapter.
+ /// </summary>
+ public class Chapter : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Chapter"/> class.
+ /// </summary>
+ /// <param name="language">ISO-639-3 3-character language codes.</param>
+ /// <param name="startTime">The start time for this chapter.</param>
+ /// <param name="release">The release.</param>
+ public Chapter(string language, long startTime, Release release)
+ {
+ if (string.IsNullOrEmpty(language))
+ {
+ throw new ArgumentNullException(nameof(language));
+ }
+
+ Language = language;
+ StartTime = startTime;
+
+ if (release == null)
+ {
+ throw new ArgumentNullException(nameof(release));
+ }
+
+ release.Chapters.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Chapter"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Chapter()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the language.
+ /// </summary>
+ /// <remarks>
+ /// Required, Min length = 3, Max length = 3
+ /// ISO-639-3 3-character language codes.
+ /// </remarks>
+ [Required]
+ [MinLength(3)]
+ [MaxLength(3)]
+ [StringLength(3)]
+ public string Language { get; set; }
+
+ /// <summary>
+ /// Gets or sets the start time.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public long StartTime { get; set; }
+
+ /// <summary>
+ /// Gets or sets the end time.
+ /// </summary>
+ public long? EndTime { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Collection.cs b/Jellyfin.Data/Entities/Libraries/Collection.cs
new file mode 100644
index 000000000..2e1bbcfb6
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Collection.cs
@@ -0,0 +1,55 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a collection.
+ /// </summary>
+ public class Collection : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Collection"/> class.
+ /// </summary>
+ public Collection()
+ {
+ Items = new HashSet<CollectionItem>();
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Name { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing this collection's items.
+ /// </summary>
+ public virtual ICollection<CollectionItem> Items { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/CollectionItem.cs b/Jellyfin.Data/Entities/Libraries/CollectionItem.cs
new file mode 100644
index 000000000..c9306f630
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/CollectionItem.cs
@@ -0,0 +1,94 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a collection item.
+ /// </summary>
+ public class CollectionItem : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CollectionItem"/> class.
+ /// </summary>
+ /// <param name="collection">The collection.</param>
+ /// <param name="previous">The previous item.</param>
+ /// <param name="next">The next item.</param>
+ public CollectionItem(Collection collection, CollectionItem previous, CollectionItem next)
+ {
+ if (collection == null)
+ {
+ throw new ArgumentNullException(nameof(collection));
+ }
+
+ collection.Items.Add(this);
+
+ if (next != null)
+ {
+ Next = next;
+ next.Previous = this;
+ }
+
+ if (previous != null)
+ {
+ Previous = previous;
+ previous.Next = this;
+ }
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CollectionItem"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected CollectionItem()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets the library item.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public virtual LibraryItem LibraryItem { get; set; }
+
+ /// <summary>
+ /// Gets or sets the next item in the collection.
+ /// </summary>
+ /// <remarks>
+ /// TODO check if this properly updated dependant and has the proper principal relationship
+ /// </remarks>
+ public virtual CollectionItem Next { get; set; }
+
+ /// <summary>
+ /// Gets or sets the previous item in the collection.
+ /// </summary>
+ /// <remarks>
+ /// TODO check if this properly updated dependant and has the proper principal relationship
+ /// </remarks>
+ public virtual CollectionItem Previous { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Company.cs b/Jellyfin.Data/Entities/Libraries/Company.cs
new file mode 100644
index 000000000..02da26bc2
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Company.cs
@@ -0,0 +1,67 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a company.
+ /// </summary>
+ public class Company : IHasCompanies, IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Company"/> class.
+ /// </summary>
+ /// <param name="owner">The owner of this company.</param>
+ public Company(IHasCompanies owner)
+ {
+ owner?.Companies.Add(this);
+
+ CompanyMetadata = new HashSet<CompanyMetadata>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Company"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Company()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the metadata.
+ /// </summary>
+ public virtual ICollection<CompanyMetadata> CompanyMetadata { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing this company's child companies.
+ /// </summary>
+ public virtual ICollection<Company> ChildCompanies { get; protected set; }
+
+ /// <inheritdoc />
+ [NotMapped]
+ public ICollection<Company> Companies => ChildCompanies;
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs b/Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs
new file mode 100644
index 000000000..60cc96a34
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/CompanyMetadata.cs
@@ -0,0 +1,74 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity holding metadata for a <see cref="Company"/>.
+ /// </summary>
+ public class CompanyMetadata : Metadata
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompanyMetadata"/> class.
+ /// </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="company">The company.</param>
+ public CompanyMetadata(string title, string language, Company company) : base(title, language)
+ {
+ if (company == null)
+ {
+ throw new ArgumentNullException(nameof(company));
+ }
+
+ company.CompanyMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CompanyMetadata"/> class.
+ /// </summary>
+ protected CompanyMetadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the description.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 65535.
+ /// </remarks>
+ [MaxLength(65535)]
+ [StringLength(65535)]
+ public string Description { get; set; }
+
+ /// <summary>
+ /// Gets or sets the headquarters.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 255.
+ /// </remarks>
+ [MaxLength(255)]
+ [StringLength(255)]
+ public string Headquarters { get; set; }
+
+ /// <summary>
+ /// Gets or sets the country code.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 2.
+ /// </remarks>
+ [MaxLength(2)]
+ [StringLength(2)]
+ public string Country { get; set; }
+
+ /// <summary>
+ /// Gets or sets the homepage.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Homepage { get; set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/CustomItem.cs b/Jellyfin.Data/Entities/Libraries/CustomItem.cs
new file mode 100644
index 000000000..6a4f0a537
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/CustomItem.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a custom item.
+ /// </summary>
+ public class CustomItem : LibraryItem, IHasReleases
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CustomItem"/> class.
+ /// </summary>
+ public CustomItem()
+ {
+ CustomItemMetadata = new HashSet<CustomItemMetadata>();
+ Releases = new HashSet<Release>();
+ }
+
+ /// <summary>
+ /// Gets or sets a collection containing the metadata for this item.
+ /// </summary>
+ public virtual ICollection<CustomItemMetadata> CustomItemMetadata { get; protected set; }
+
+ /// <inheritdoc />
+ public virtual ICollection<Release> Releases { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs b/Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs
new file mode 100644
index 000000000..bc1835528
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/CustomItemMetadata.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity containing metadata for a custom item.
+ /// </summary>
+ public class CustomItemMetadata : Metadata
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CustomItemMetadata"/> class.
+ /// </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="item">The item.</param>
+ public CustomItemMetadata(string title, string language, CustomItem item) : base(title, language)
+ {
+ if (item == null)
+ {
+ throw new ArgumentNullException(nameof(item));
+ }
+
+ item.CustomItemMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CustomItemMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected CustomItemMetadata()
+ {
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Episode.cs b/Jellyfin.Data/Entities/Libraries/Episode.cs
new file mode 100644
index 000000000..430a11e3c
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Episode.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing an episode.
+ /// </summary>
+ public class Episode : LibraryItem, IHasReleases
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Episode"/> class.
+ /// </summary>
+ /// <param name="season">The season.</param>
+ public Episode(Season season)
+ {
+ if (season == null)
+ {
+ throw new ArgumentNullException(nameof(season));
+ }
+
+ season.Episodes.Add(this);
+
+ Releases = new HashSet<Release>();
+ EpisodeMetadata = new HashSet<EpisodeMetadata>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Episode"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Episode()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the episode number.
+ /// </summary>
+ public int? EpisodeNumber { get; set; }
+
+ /// <inheritdoc />
+ public virtual ICollection<Release> Releases { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the metadata for this episode.
+ /// </summary>
+ public virtual ICollection<EpisodeMetadata> EpisodeMetadata { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs b/Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs
new file mode 100644
index 000000000..348100cb4
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/EpisodeMetadata.cs
@@ -0,0 +1,67 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity containing metadata for an <see cref="Episode"/>.
+ /// </summary>
+ public class EpisodeMetadata : Metadata
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EpisodeMetadata"/> class.
+ /// </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="episode">The episode.</param>
+ public EpisodeMetadata(string title, string language, Episode episode) : base(title, language)
+ {
+ if (episode == null)
+ {
+ throw new ArgumentNullException(nameof(episode));
+ }
+
+ episode.EpisodeMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="EpisodeMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected EpisodeMetadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the outline.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Outline { get; set; }
+
+ /// <summary>
+ /// Gets or sets the plot.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 65535.
+ /// </remarks>
+ [MaxLength(65535)]
+ [StringLength(65535)]
+ public string Plot { get; set; }
+
+ /// <summary>
+ /// Gets or sets the tagline.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Tagline { get; set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Genre.cs b/Jellyfin.Data/Entities/Libraries/Genre.cs
new file mode 100644
index 000000000..aeedd7bfd
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Genre.cs
@@ -0,0 +1,75 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a genre.
+ /// </summary>
+ public class Genre : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Genre"/> class.
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <param name="metadata">The metadata.</param>
+ public Genre(string name, Metadata metadata)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ Name = name;
+
+ if (metadata == null)
+ {
+ throw new ArgumentNullException(nameof(metadata));
+ }
+
+ metadata.Genres.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Genre"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Genre()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Indexed, Required, Max length = 255.
+ /// </remarks>
+ [Required]
+ [MaxLength(255)]
+ [StringLength(255)]
+ public string Name { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Library.cs b/Jellyfin.Data/Entities/Libraries/Library.cs
new file mode 100644
index 000000000..4f82a2e2a
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Library.cs
@@ -0,0 +1,76 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a library.
+ /// </summary>
+ public class Library : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Library"/> class.
+ /// </summary>
+ /// <param name="name">The name of the library.</param>
+ public Library(string name)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ Name = name;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Library"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Library()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 128.
+ /// </remarks>
+ [Required]
+ [MaxLength(128)]
+ [StringLength(128)]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the root path of the library.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public string Path { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/LibraryItem.cs b/Jellyfin.Data/Entities/Libraries/LibraryItem.cs
new file mode 100644
index 000000000..a9167aa7f
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/LibraryItem.cs
@@ -0,0 +1,63 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a library item.
+ /// </summary>
+ public abstract class LibraryItem : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LibraryItem"/> class.
+ /// </summary>
+ /// <param name="library">The library of this item.</param>
+ protected LibraryItem(Library library)
+ {
+ DateAdded = DateTime.UtcNow;
+ Library = library;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="LibraryItem"/> class.
+ /// </summary>
+ protected LibraryItem()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the date this library item was added.
+ /// </summary>
+ public DateTime DateAdded { get; protected set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the library of this item.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public virtual Library Library { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/MediaFile.cs b/Jellyfin.Data/Entities/Libraries/MediaFile.cs
new file mode 100644
index 000000000..8bc649c98
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/MediaFile.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Enums;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a file on disk.
+ /// </summary>
+ public class MediaFile : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MediaFile"/> class.
+ /// </summary>
+ /// <param name="path">The path relative to the LibraryRoot.</param>
+ /// <param name="kind">The file kind.</param>
+ /// <param name="release">The release.</param>
+ public MediaFile(string path, MediaFileKind kind, Release release)
+ {
+ if (string.IsNullOrEmpty(path))
+ {
+ throw new ArgumentNullException(nameof(path));
+ }
+
+ Path = path;
+ Kind = kind;
+
+ if (release == null)
+ {
+ throw new ArgumentNullException(nameof(release));
+ }
+
+ release.MediaFiles.Add(this);
+
+ MediaFileStreams = new HashSet<MediaFileStream>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MediaFile"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected MediaFile()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the path relative to the library root.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 65535.
+ /// </remarks>
+ [Required]
+ [MaxLength(65535)]
+ [StringLength(65535)]
+ public string Path { get; set; }
+
+ /// <summary>
+ /// Gets or sets the kind of media file.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public MediaFileKind Kind { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the streams in this file.
+ /// </summary>
+ public virtual ICollection<MediaFileStream> MediaFileStreams { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/MediaFileStream.cs b/Jellyfin.Data/Entities/Libraries/MediaFileStream.cs
new file mode 100644
index 000000000..5b03e260e
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/MediaFileStream.cs
@@ -0,0 +1,67 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a stream in a media file.
+ /// </summary>
+ public class MediaFileStream : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MediaFileStream"/> class.
+ /// </summary>
+ /// <param name="streamNumber">The number of this stream.</param>
+ /// <param name="mediaFile">The media file.</param>
+ public MediaFileStream(int streamNumber, MediaFile mediaFile)
+ {
+ StreamNumber = streamNumber;
+
+ if (mediaFile == null)
+ {
+ throw new ArgumentNullException(nameof(mediaFile));
+ }
+
+ mediaFile.MediaFileStreams.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MediaFileStream"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected MediaFileStream()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the stream number.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public int StreamNumber { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Metadata.cs b/Jellyfin.Data/Entities/Libraries/Metadata.cs
new file mode 100644
index 000000000..877bb5fbd
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Metadata.cs
@@ -0,0 +1,165 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An abstract class that holds metadata.
+ /// </summary>
+ public abstract class Metadata : IHasArtwork, IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Metadata"/> class.
+ /// </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)
+ {
+ if (string.IsNullOrEmpty(title))
+ {
+ throw new ArgumentNullException(nameof(title));
+ }
+
+ if (string.IsNullOrEmpty(language))
+ {
+ throw new ArgumentNullException(nameof(language));
+ }
+
+ Title = title;
+ Language = language;
+ DateAdded = DateTime.UtcNow;
+ DateModified = DateAdded;
+
+ PersonRoles = new HashSet<PersonRole>();
+ Genres = new HashSet<Genre>();
+ Artwork = new HashSet<Artwork>();
+ Ratings = new HashSet<Rating>();
+ Sources = new HashSet<MetadataProviderId>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Metadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to being abstract.
+ /// </remarks>
+ protected Metadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the title.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 1024.
+ /// </remarks>
+ [Required]
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Title { get; set; }
+
+ /// <summary>
+ /// Gets or sets the original title.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string OriginalTitle { get; set; }
+
+ /// <summary>
+ /// Gets or sets the sort title.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string SortTitle { get; set; }
+
+ /// <summary>
+ /// Gets or sets the language.
+ /// </summary>
+ /// <remarks>
+ /// Required, Min length = 3, Max length = 3.
+ /// ISO-639-3 3-character language codes.
+ /// </remarks>
+ [Required]
+ [MinLength(3)]
+ [MaxLength(3)]
+ [StringLength(3)]
+ public string Language { get; set; }
+
+ /// <summary>
+ /// Gets or sets the release date.
+ /// </summary>
+ public DateTimeOffset? ReleaseDate { get; set; }
+
+ /// <summary>
+ /// Gets or sets the date added.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public DateTime DateAdded { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the date modified.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public DateTime DateModified { get; set; }
+
+ /// <summary>
+ /// Gets or sets the row version.
+ /// </summary>
+ /// <remarks>
+ /// Required, ConcurrencyToken.
+ /// </remarks>
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the person roles for this item.
+ /// </summary>
+ public virtual ICollection<PersonRole> PersonRoles { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the generes for this item.
+ /// </summary>
+ public virtual ICollection<Genre> Genres { get; protected set; }
+
+ /// <inheritdoc />
+ public virtual ICollection<Artwork> Artwork { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the ratings for this item.
+ /// </summary>
+ public virtual ICollection<Rating> Ratings { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the metadata sources for this item.
+ /// </summary>
+ public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/MetadataProvider.cs b/Jellyfin.Data/Entities/Libraries/MetadataProvider.cs
new file mode 100644
index 000000000..a18a612bc
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/MetadataProvider.cs
@@ -0,0 +1,67 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a metadata provider.
+ /// </summary>
+ public class MetadataProvider : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MetadataProvider"/> class.
+ /// </summary>
+ /// <param name="name">The name of the metadata provider.</param>
+ public MetadataProvider(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ Name = name;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MetadataProvider"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected MetadataProvider()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 1024.
+ /// </remarks>
+ [Required]
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Name { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs b/Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs
new file mode 100644
index 000000000..6e6de598e
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/MetadataProviderId.cs
@@ -0,0 +1,83 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a unique identifier for a metadata provider.
+ /// </summary>
+ public class MetadataProviderId : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MetadataProviderId"/> class.
+ /// </summary>
+ /// <param name="providerId">The provider id.</param>
+ /// <param name="metadata">The metadata entity.</param>
+ public MetadataProviderId(string providerId, Metadata metadata)
+ {
+ if (string.IsNullOrEmpty(providerId))
+ {
+ throw new ArgumentNullException(nameof(providerId));
+ }
+
+ ProviderId = providerId;
+
+ if (metadata == null)
+ {
+ throw new ArgumentNullException(nameof(metadata));
+ }
+
+ metadata.Sources.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MetadataProviderId"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected MetadataProviderId()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the provider id.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 255.
+ /// </remarks>
+ [Required]
+ [MaxLength(255)]
+ [StringLength(255)]
+ public string ProviderId { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets the metadata provider.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public virtual MetadataProvider MetadataProvider { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Movie.cs b/Jellyfin.Data/Entities/Libraries/Movie.cs
new file mode 100644
index 000000000..0a8cc83dd
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Movie.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a movie.
+ /// </summary>
+ public class Movie : LibraryItem, IHasReleases
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Movie"/> class.
+ /// </summary>
+ public Movie()
+ {
+ Releases = new HashSet<Release>();
+ MovieMetadata = new HashSet<MovieMetadata>();
+ }
+
+ /// <inheritdoc />
+ public virtual ICollection<Release> Releases { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the metadata for this movie.
+ /// </summary>
+ public virtual ICollection<MovieMetadata> MovieMetadata { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/MovieMetadata.cs b/Jellyfin.Data/Entities/Libraries/MovieMetadata.cs
new file mode 100644
index 000000000..31102bf13
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/MovieMetadata.cs
@@ -0,0 +1,85 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity holding the metadata for a movie.
+ /// </summary>
+ public class MovieMetadata : Metadata, IHasCompanies
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovieMetadata"/> class.
+ /// </summary>
+ /// <param name="title">The title or name of the movie.</param>
+ /// <param name="language">ISO-639-3 3-character language codes.</param>
+ /// <param name="movie">The movie.</param>
+ public MovieMetadata(string title, string language, Movie movie) : base(title, language)
+ {
+ Studios = new HashSet<Company>();
+
+ movie.MovieMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MovieMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected MovieMetadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the outline.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Outline { get; set; }
+
+ /// <summary>
+ /// Gets or sets the tagline.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Tagline { get; set; }
+
+ /// <summary>
+ /// Gets or sets the plot.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 65535.
+ /// </remarks>
+ [MaxLength(65535)]
+ [StringLength(65535)]
+ public string Plot { get; set; }
+
+ /// <summary>
+ /// Gets or sets the country code.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 2.
+ /// </remarks>
+ [MaxLength(2)]
+ [StringLength(2)]
+ public string Country { get; set; }
+
+ /// <summary>
+ /// Gets or sets the studios that produced this movie.
+ /// </summary>
+ public virtual ICollection<Company> Studios { get; protected set; }
+
+ /// <inheritdoc />
+ [NotMapped]
+ public ICollection<Company> Companies => Studios;
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/MusicAlbum.cs b/Jellyfin.Data/Entities/Libraries/MusicAlbum.cs
new file mode 100644
index 000000000..2ed1f78c5
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/MusicAlbum.cs
@@ -0,0 +1,29 @@
+using System.Collections.Generic;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a music album.
+ /// </summary>
+ public class MusicAlbum : LibraryItem
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MusicAlbum"/> class.
+ /// </summary>
+ public MusicAlbum()
+ {
+ MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>();
+ Tracks = new HashSet<Track>();
+ }
+
+ /// <summary>
+ /// Gets or sets a collection containing the album metadata.
+ /// </summary>
+ public virtual ICollection<MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the tracks.
+ /// </summary>
+ public virtual ICollection<Track> Tracks { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs b/Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs
new file mode 100644
index 000000000..cc5919bfe
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/MusicAlbumMetadata.cs
@@ -0,0 +1,69 @@
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity holding the metadata for a music album.
+ /// </summary>
+ public class MusicAlbumMetadata : Metadata
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MusicAlbumMetadata"/> class.
+ /// </summary>
+ /// <param name="title">The title or name of the album.</param>
+ /// <param name="language">ISO-639-3 3-character language codes.</param>
+ /// <param name="album">The music album.</param>
+ public MusicAlbumMetadata(string title, string language, MusicAlbum album) : base(title, language)
+ {
+ Labels = new HashSet<Company>();
+
+ album.MusicAlbumMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="MusicAlbumMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected MusicAlbumMetadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the barcode.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 255.
+ /// </remarks>
+ [MaxLength(255)]
+ [StringLength(255)]
+ public string Barcode { get; set; }
+
+ /// <summary>
+ /// Gets or sets the label number.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 255.
+ /// </remarks>
+ [MaxLength(255)]
+ [StringLength(255)]
+ public string LabelNumber { get; set; }
+
+ /// <summary>
+ /// Gets or sets the country code.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 2.
+ /// </remarks>
+ [MaxLength(2)]
+ [StringLength(2)]
+ public string Country { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the labels.
+ /// </summary>
+ public virtual ICollection<Company> Labels { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Person.cs b/Jellyfin.Data/Entities/Libraries/Person.cs
new file mode 100644
index 000000000..8beb3dd08
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Person.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a person.
+ /// </summary>
+ public class Person : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Person"/> class.
+ /// </summary>
+ /// <param name="name">The name of the person.</param>
+ public Person(string name)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ Name = name;
+ DateAdded = DateTime.UtcNow;
+ DateModified = DateAdded;
+
+ Sources = new HashSet<MetadataProviderId>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Person"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Person()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 1024.
+ /// </remarks>
+ [Required]
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the source id.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 255.
+ /// </remarks>
+ [MaxLength(256)]
+ [StringLength(256)]
+ public string SourceId { get; set; }
+
+ /// <summary>
+ /// Gets or sets the date added.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public DateTime DateAdded { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the date modified.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public DateTime DateModified { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets a list of metadata sources for this person.
+ /// </summary>
+ public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/PersonRole.cs b/Jellyfin.Data/Entities/Libraries/PersonRole.cs
new file mode 100644
index 000000000..5290228d6
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/PersonRole.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Enums;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a person's role in media.
+ /// </summary>
+ public class PersonRole : IHasArtwork, IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonRole"/> class.
+ /// </summary>
+ /// <param name="type">The role type.</param>
+ /// <param name="metadata">The metadata.</param>
+ public PersonRole(PersonRoleType type, Metadata metadata)
+ {
+ Type = type;
+
+ if (metadata == null)
+ {
+ throw new ArgumentNullException(nameof(metadata));
+ }
+
+ metadata.PersonRoles.Add(this);
+
+ Sources = new HashSet<MetadataProviderId>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PersonRole"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected PersonRole()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name of the person's role.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Role { get; set; }
+
+ /// <summary>
+ /// Gets or sets the person's role type.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public PersonRoleType Type { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the person.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ [Required]
+ public virtual Person Person { get; set; }
+
+ /// <inheritdoc />
+ public virtual ICollection<Artwork> Artwork { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the metadata sources for this person role.
+ /// </summary>
+ public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Photo.cs b/Jellyfin.Data/Entities/Libraries/Photo.cs
new file mode 100644
index 000000000..44338a4ce
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Photo.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a photo.
+ /// </summary>
+ public class Photo : LibraryItem, IHasReleases
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Photo"/> class.
+ /// </summary>
+ public Photo()
+ {
+ PhotoMetadata = new HashSet<PhotoMetadata>();
+ Releases = new HashSet<Release>();
+ }
+
+ /// <summary>
+ /// Gets or sets a collection containing the photo metadata.
+ /// </summary>
+ public virtual ICollection<PhotoMetadata> PhotoMetadata { get; protected set; }
+
+ /// <inheritdoc />
+ public virtual ICollection<Release> Releases { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/PhotoMetadata.cs b/Jellyfin.Data/Entities/Libraries/PhotoMetadata.cs
new file mode 100644
index 000000000..1ef9dd5f9
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/PhotoMetadata.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity that holds metadata for a photo.
+ /// </summary>
+ public class PhotoMetadata : Metadata
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PhotoMetadata"/> class.
+ /// </summary>
+ /// <param name="title">The title or name of the photo.</param>
+ /// <param name="language">ISO-639-3 3-character language codes.</param>
+ /// <param name="photo">The photo.</param>
+ public PhotoMetadata(string title, string language, Photo photo) : base(title, language)
+ {
+ if (photo == null)
+ {
+ throw new ArgumentNullException(nameof(photo));
+ }
+
+ photo.PhotoMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PhotoMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected PhotoMetadata()
+ {
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Rating.cs b/Jellyfin.Data/Entities/Libraries/Rating.cs
new file mode 100644
index 000000000..ba054a39e
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Rating.cs
@@ -0,0 +1,78 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a rating for an entity.
+ /// </summary>
+ public class Rating : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Rating"/> class.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ /// <param name="metadata">The metadata.</param>
+ public Rating(double value, Metadata metadata)
+ {
+ Value = value;
+
+ if (metadata == null)
+ {
+ throw new ArgumentNullException(nameof(metadata));
+ }
+
+ metadata.Ratings.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Rating"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Rating()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the value.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public double Value { get; set; }
+
+ /// <summary>
+ /// Gets or sets the number of votes.
+ /// </summary>
+ public int? Votes { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets the rating type.
+ /// If this is <c>null</c> it's the internal user rating.
+ /// </summary>
+ public virtual RatingSource RatingType { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/RatingSource.cs b/Jellyfin.Data/Entities/Libraries/RatingSource.cs
new file mode 100644
index 000000000..549f41804
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/RatingSource.cs
@@ -0,0 +1,92 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// This is the entity to store review ratings, not age ratings.
+ /// </summary>
+ public class RatingSource : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RatingSource"/> class.
+ /// </summary>
+ /// <param name="minimumValue">The minimum value.</param>
+ /// <param name="maximumValue">The maximum value.</param>
+ /// <param name="rating">The rating.</param>
+ public RatingSource(double minimumValue, double maximumValue, Rating rating)
+ {
+ MinimumValue = minimumValue;
+ MaximumValue = maximumValue;
+
+ if (rating == null)
+ {
+ throw new ArgumentNullException(nameof(rating));
+ }
+
+ rating.RatingType = this;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RatingSource"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected RatingSource()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the minimum value.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public double MinimumValue { get; set; }
+
+ /// <summary>
+ /// Gets or sets the maximum value.
+ /// </summary>
+ /// <remarks>
+ /// Required.
+ /// </remarks>
+ public double MaximumValue { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets the metadata source.
+ /// </summary>
+ public virtual MetadataProviderId Source { get; set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Release.cs b/Jellyfin.Data/Entities/Libraries/Release.cs
new file mode 100644
index 000000000..43c7080d7
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Release.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a release for a library item, eg. Director's cut vs. standard.
+ /// </summary>
+ public class Release : IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Release"/> class.
+ /// </summary>
+ /// <param name="name">The name of this release.</param>
+ /// <param name="owner">The owner of this release.</param>
+ public Release(string name, IHasReleases owner)
+ {
+ if (string.IsNullOrEmpty(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ Name = name;
+
+ owner?.Releases.Add(this);
+
+ MediaFiles = new HashSet<MediaFile>();
+ Chapters = new HashSet<Chapter>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Release"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Release()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <remarks>
+ /// Identity, Indexed, Required.
+ /// </remarks>
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets the name.
+ /// </summary>
+ /// <remarks>
+ /// Required, Max length = 1024.
+ /// </remarks>
+ [Required]
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Name { get; set; }
+
+ /// <inheritdoc />
+ [ConcurrencyCheck]
+ public uint RowVersion { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the media files for this release.
+ /// </summary>
+ public virtual ICollection<MediaFile> MediaFiles { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the chapters for this release.
+ /// </summary>
+ public virtual ICollection<Chapter> Chapters { get; protected set; }
+
+ /// <inheritdoc />
+ public void OnSavingChanges()
+ {
+ RowVersion++;
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Season.cs b/Jellyfin.Data/Entities/Libraries/Season.cs
new file mode 100644
index 000000000..eef788bad
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Season.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a season.
+ /// </summary>
+ public class Season : LibraryItem
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Season"/> class.
+ /// </summary>
+ /// <param name="series">The series.</param>
+ public Season(Series series)
+ {
+ if (series == null)
+ {
+ throw new ArgumentNullException(nameof(series));
+ }
+
+ series.Seasons.Add(this);
+
+ Episodes = new HashSet<Episode>();
+ SeasonMetadata = new HashSet<SeasonMetadata>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Season"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Season()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the season number.
+ /// </summary>
+ public int? SeasonNumber { get; set; }
+
+ /// <summary>
+ /// Gets or sets the season metadata.
+ /// </summary>
+ public virtual ICollection<SeasonMetadata> SeasonMetadata { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the number of episodes.
+ /// </summary>
+ public virtual ICollection<Episode> Episodes { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs b/Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs
new file mode 100644
index 000000000..eedeb089e
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/SeasonMetadata.cs
@@ -0,0 +1,47 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity that holds metadata for seasons.
+ /// </summary>
+ public class SeasonMetadata : Metadata
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SeasonMetadata"/> class.
+ /// </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="season">The season.</param>
+ public SeasonMetadata(string title, string language, Season season) : base(title, language)
+ {
+ if (season == null)
+ {
+ throw new ArgumentNullException(nameof(season));
+ }
+
+ season.SeasonMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SeasonMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected SeasonMetadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the outline.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Outline { get; set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Series.cs b/Jellyfin.Data/Entities/Libraries/Series.cs
new file mode 100644
index 000000000..e959c1fe0
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Series.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a a series.
+ /// </summary>
+ public class Series : LibraryItem
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Series"/> class.
+ /// </summary>
+ public Series()
+ {
+ DateAdded = DateTime.UtcNow;
+ Seasons = new HashSet<Season>();
+ SeriesMetadata = new HashSet<SeriesMetadata>();
+ }
+
+ /// <summary>
+ /// Gets or sets the days of week.
+ /// </summary>
+ public DayOfWeek? AirsDayOfWeek { get; set; }
+
+ /// <summary>
+ /// Gets or sets the time the show airs, ignore the date portion.
+ /// </summary>
+ public DateTimeOffset? AirsTime { get; set; }
+
+ /// <summary>
+ /// Gets or sets the date the series first aired.
+ /// </summary>
+ public DateTime? FirstAired { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the series metadata.
+ /// </summary>
+ public virtual ICollection<SeriesMetadata> SeriesMetadata { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the seasons.
+ /// </summary>
+ public virtual ICollection<Season> Seasons { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs b/Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs
new file mode 100644
index 000000000..898f3006d
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/SeriesMetadata.cs
@@ -0,0 +1,91 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations.Schema;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing series metadata.
+ /// </summary>
+ public class SeriesMetadata : Metadata, IHasCompanies
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SeriesMetadata"/> class.
+ /// </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="series">The series.</param>
+ public SeriesMetadata(string title, string language, Series series) : base(title, language)
+ {
+ if (series == null)
+ {
+ throw new ArgumentNullException(nameof(series));
+ }
+
+ series.SeriesMetadata.Add(this);
+
+ Networks = new HashSet<Company>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="SeriesMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected SeriesMetadata()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the outline.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Outline { get; set; }
+
+ /// <summary>
+ /// Gets or sets the plot.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 65535.
+ /// </remarks>
+ [MaxLength(65535)]
+ [StringLength(65535)]
+ public string Plot { get; set; }
+
+ /// <summary>
+ /// Gets or sets the tagline.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 1024.
+ /// </remarks>
+ [MaxLength(1024)]
+ [StringLength(1024)]
+ public string Tagline { get; set; }
+
+ /// <summary>
+ /// Gets or sets the country code.
+ /// </summary>
+ /// <remarks>
+ /// Max length = 2.
+ /// </remarks>
+ [MaxLength(2)]
+ [StringLength(2)]
+ public string Country { get; set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the networks.
+ /// </summary>
+ public virtual ICollection<Company> Networks { get; protected set; }
+
+ /// <inheritdoc />
+ [NotMapped]
+ public ICollection<Company> Companies => Networks;
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/Track.cs b/Jellyfin.Data/Entities/Libraries/Track.cs
new file mode 100644
index 000000000..09ce82a9b
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/Track.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using Jellyfin.Data.Interfaces;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity representing a track.
+ /// </summary>
+ public class Track : LibraryItem, IHasReleases
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Track"/> class.
+ /// </summary>
+ /// <param name="album">The album.</param>
+ public Track(MusicAlbum album)
+ {
+ if (album == null)
+ {
+ throw new ArgumentNullException(nameof(album));
+ }
+
+ album.Tracks.Add(this);
+
+ Releases = new HashSet<Release>();
+ TrackMetadata = new HashSet<TrackMetadata>();
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="Track"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected Track()
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the track number.
+ /// </summary>
+ public int? TrackNumber { get; set; }
+
+ /// <inheritdoc />
+ public virtual ICollection<Release> Releases { get; protected set; }
+
+ /// <summary>
+ /// Gets or sets a collection containing the track metadata.
+ /// </summary>
+ public virtual ICollection<TrackMetadata> TrackMetadata { get; protected set; }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Libraries/TrackMetadata.cs b/Jellyfin.Data/Entities/Libraries/TrackMetadata.cs
new file mode 100644
index 000000000..048068a1a
--- /dev/null
+++ b/Jellyfin.Data/Entities/Libraries/TrackMetadata.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace Jellyfin.Data.Entities.Libraries
+{
+ /// <summary>
+ /// An entity holding metadata for a track.
+ /// </summary>
+ public class TrackMetadata : Metadata
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TrackMetadata"/> class.
+ /// </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="track">The track.</param>
+ public TrackMetadata(string title, string language, Track track) : base(title, language)
+ {
+ if (track == null)
+ {
+ throw new ArgumentNullException(nameof(track));
+ }
+
+ track.TrackMetadata.Add(this);
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="TrackMetadata"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Default constructor. Protected due to required properties, but present because EF needs it.
+ /// </remarks>
+ protected TrackMetadata()
+ {
+ }
+ }
+}
diff --git a/Jellyfin.Data/Entities/Library.cs b/Jellyfin.Data/Entities/Library.cs
deleted file mode 100644
index 23cc9bd7d..000000000
--- a/Jellyfin.Data/Entities/Library.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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]
- [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 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
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/LibraryItem.cs b/Jellyfin.Data/Entities/LibraryItem.cs
deleted file mode 100644
index 00b2f9497..000000000
--- a/Jellyfin.Data/Entities/LibraryItem.cs
+++ /dev/null
@@ -1,175 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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>
- /// <param name="dateadded">The date the object was added.</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
- {
- Guid oldValue = _UrlId;
- SetUrlId(oldValue, ref value);
- if (oldValue != value)
- {
- _UrlId = 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>
- /// 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
deleted file mode 100644
index 07e16fff4..000000000
--- a/Jellyfin.Data/Entities/LibraryRoot.cs
+++ /dev/null
@@ -1,199 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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]
- [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
- {
- string oldValue = _Path;
- SetPath(oldValue, ref value);
- if (oldValue != value)
- {
- _Path = 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)
- {
- _NetworkPath = value;
- }
- }
- }
-
- /// <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
deleted file mode 100644
index b69dbe2fa..000000000
--- a/Jellyfin.Data/Entities/MediaFile.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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 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
- {
- string oldValue = _Path;
- SetPath(oldValue, ref value);
- if (oldValue != value)
- {
- _Path = 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
- {
- Enums.MediaFileKind value = _Kind;
- GetKind(ref value);
- return _Kind = value;
- }
-
- set
- {
- Enums.MediaFileKind oldValue = _Kind;
- SetKind(oldValue, ref value);
- if (oldValue != value)
- {
- _Kind = value;
- }
- }
- }
-
- /// <summary>
- /// Required, ConcurrenyToken.
- /// </summary>
- [ConcurrencyCheck]
- [Required]
- public uint RowVersion { get; set; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- [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
deleted file mode 100644
index 1c59e663d..000000000
--- a/Jellyfin.Data/Entities/MediaFileStream.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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, 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
- {
- 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)
- {
- _StreamNumber = value;
- }
- }
- }
-
- /// <summary>
- /// Required, ConcurrenyToken.
- /// </summary>
- [ConcurrencyCheck]
- [Required]
- public uint RowVersion { get; set; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Metadata.cs b/Jellyfin.Data/Entities/Metadata.cs
deleted file mode 100644
index 42525fa99..000000000
--- a/Jellyfin.Data/Entities/Metadata.cs
+++ /dev/null
@@ -1,399 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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 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>
- /// <param name="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- string value = _OriginalTitle;
- GetOriginalTitle(ref value);
- return _OriginalTitle = value;
- }
-
- set
- {
- string oldValue = _OriginalTitle;
- SetOriginalTitle(oldValue, ref value);
- if (oldValue != value)
- {
- _OriginalTitle = 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)
- {
- _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)
- {
- _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)
- {
- _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; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- [ForeignKey("PersonRole_PersonRoles_Id")]
- public virtual ICollection<PersonRole> PersonRoles { get; protected set; }
-
- [ForeignKey("PersonRole_PersonRoles_Id")]
- public virtual ICollection<Genre> Genres { get; protected set; }
-
- [ForeignKey("PersonRole_PersonRoles_Id")]
- public virtual ICollection<Artwork> Artwork { get; protected set; }
-
- [ForeignKey("PersonRole_PersonRoles_Id")]
- public virtual ICollection<Rating> Ratings { 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
deleted file mode 100644
index ebb2c1dbc..000000000
--- a/Jellyfin.Data/Entities/MetadataProvider.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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]
- [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 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
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/MetadataProviderId.cs b/Jellyfin.Data/Entities/MetadataProviderId.cs
deleted file mode 100644
index ca3e16b1a..000000000
--- a/Jellyfin.Data/Entities/MetadataProviderId.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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, 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
- {
- string value = _ProviderId;
- GetProviderId(ref value);
- return _ProviderId = value;
- }
-
- set
- {
- string oldValue = _ProviderId;
- SetProviderId(oldValue, ref value);
- if (oldValue != value)
- {
- _ProviderId = value;
- }
- }
- }
-
- /// <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
deleted file mode 100644
index 842d5b2b0..000000000
--- a/Jellyfin.Data/Entities/Movie.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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()
- {
- Releases = new HashSet<Release>();
- MovieMetadata = new HashSet<MovieMetadata>();
-
- 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>
- /// 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="dateadded">The date the object was added.</param>
- public Movie(Guid urlid, DateTime dateadded)
- {
- this.UrlId = urlid;
-
- this.Releases = new HashSet<Release>();
- this.MovieMetadata = new HashSet<MovieMetadata>();
-
- 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="dateadded">The date the object was added.</param>
- public static Movie Create(Guid urlid, DateTime dateadded)
- {
- return new Movie(urlid, dateadded);
- }
-
- /*************************************************************************
- * Properties
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- [ForeignKey("Release_Releases_Id")]
- public virtual ICollection<Release> Releases { 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
deleted file mode 100644
index a6c82dda8..000000000
--- a/Jellyfin.Data/Entities/MovieMetadata.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- 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
- {
- string oldValue = _Plot;
- SetPlot(oldValue, ref value);
- if (oldValue != value)
- {
- _Plot = 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)
- {
- _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;
- }
- }
- }
-
- /*************************************************************************
- * 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
deleted file mode 100644
index e03c3bfb0..000000000
--- a/Jellyfin.Data/Entities/MusicAlbum.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- public partial class MusicAlbum : LibraryItem
- {
- partial void 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>();
-
- Init();
- }
-
- /// <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();
- }
-
- /// <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="dateadded">The date the object was added.</param>
- public MusicAlbum(Guid urlid, DateTime dateadded)
- {
- this.UrlId = urlid;
-
- this.MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>();
- this.Tracks = new HashSet<Track>();
-
- 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="dateadded">The date the object was added.</param>
- public static MusicAlbum Create(Guid urlid, DateTime dateadded)
- {
- return new MusicAlbum(urlid, dateadded);
- }
-
- /*************************************************************************
- * Properties
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- [ForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id")]
- public virtual ICollection<MusicAlbumMetadata> MusicAlbumMetadata { 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
deleted file mode 100644
index 01ad736ce..000000000
--- a/Jellyfin.Data/Entities/MusicAlbumMetadata.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- string oldValue = _LabelNumber;
- SetLabelNumber(oldValue, ref value);
- if (oldValue != value)
- {
- _LabelNumber = 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;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- [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 af3270a88..c0f67f836 100644
--- a/Jellyfin.Data/Entities/Permission.cs
+++ b/Jellyfin.Data/Entities/Permission.cs
@@ -3,13 +3,14 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Interfaces;
namespace Jellyfin.Data.Entities
{
/// <summary>
/// An entity representing whether the associated user has a specific permission.
/// </summary>
- public partial class Permission : ISavingChanges
+ public partial class Permission : IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="Permission"/> class.
diff --git a/Jellyfin.Data/Entities/Person.cs b/Jellyfin.Data/Entities/Person.cs
deleted file mode 100644
index f0cfb7322..000000000
--- a/Jellyfin.Data/Entities/Person.cs
+++ /dev/null
@@ -1,317 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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 HashSet<MetadataProviderId>();
-
- 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>
- /// Public constructor with required data.
- /// </summary>
- /// <param name="urlid"></param>
- /// <param name="name"></param>
- /// <param name="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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;
-
- this.Sources = new HashSet<MetadataProviderId>();
-
- Init();
- }
-
- /// <summary>
- /// Static create function (for use in LINQ queries, etc.)
- /// </summary>
- /// <param name="urlid"></param>
- /// <param name="name"></param>
- /// <param name="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</param>
- public static Person Create(Guid urlid, string name, DateTime dateadded, DateTime datemodified)
- {
- return new Person(urlid, name, dateadded, datemodified);
- }
-
- /*************************************************************************
- * 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>
- 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)
- {
- _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>
- /// 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>
- /// 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)
- {
- _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>
- /// 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; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * 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
deleted file mode 100644
index 895a9f47a..000000000
--- a/Jellyfin.Data/Entities/PersonRole.cs
+++ /dev/null
@@ -1,217 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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 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
- {
- string value = _Role;
- GetRole(ref value);
- return _Role = value;
- }
-
- set
- {
- string oldValue = _Role;
- SetRole(oldValue, ref value);
- if (oldValue != value)
- {
- _Role = 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
- {
- 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++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- /// <summary>
- /// Required.
- /// </summary>
- [ForeignKey("Person_Id")]
-
- public virtual Person Person { get; set; }
-
- [ForeignKey("Artwork_Artwork_Id")]
- public virtual Artwork Artwork { get; 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
deleted file mode 100644
index 7648bc212..000000000
--- a/Jellyfin.Data/Entities/Photo.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- public partial class Photo : LibraryItem
- {
- partial void 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>();
-
- Init();
- }
-
- /// <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();
- }
-
- /// <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="dateadded">The date the object was added.</param>
- public Photo(Guid urlid, DateTime dateadded)
- {
- this.UrlId = urlid;
-
- this.PhotoMetadata = new HashSet<PhotoMetadata>();
- this.Releases = new HashSet<Release>();
-
- 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="dateadded">The date the object was added.</param>
- public static Photo Create(Guid urlid, DateTime dateadded)
- {
- return new Photo(urlid, dateadded);
- }
-
- /*************************************************************************
- * Properties
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- [ForeignKey("PhotoMetadata_PhotoMetadata_Id")]
- public virtual ICollection<PhotoMetadata> PhotoMetadata { 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
deleted file mode 100644
index 3f06d3f2b..000000000
--- a/Jellyfin.Data/Entities/PhotoMetadata.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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()
- {
- 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>
- /// 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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 (_photo0 == null)
- {
- throw new ArgumentNullException(nameof(_photo0));
- }
-
- _photo0.PhotoMetadata.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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Preference.cs b/Jellyfin.Data/Entities/Preference.cs
index 0ca9d7eff..1797f0a40 100644
--- a/Jellyfin.Data/Entities/Preference.cs
+++ b/Jellyfin.Data/Entities/Preference.cs
@@ -2,13 +2,14 @@ using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Interfaces;
namespace Jellyfin.Data.Entities
{
/// <summary>
/// An entity representing a preference attached to a user or group.
/// </summary>
- public class Preference : ISavingChanges
+ public class Preference : IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="Preference"/> class.
diff --git a/Jellyfin.Data/Entities/Rating.cs b/Jellyfin.Data/Entities/Rating.cs
deleted file mode 100644
index c57b0a0e8..000000000
--- a/Jellyfin.Data/Entities/Rating.cs
+++ /dev/null
@@ -1,194 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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, 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
- {
- double oldValue = _Value;
- SetValue(oldValue, ref value);
- if (oldValue != value)
- {
- _Value = 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)
- {
- _Votes = value;
- }
- }
- }
-
- /// <summary>
- /// Required, ConcurrenyToken.
- /// </summary>
- [ConcurrencyCheck]
- [Required]
- public uint RowVersion { get; set; }
-
- public void OnSavingChanges()
- {
- RowVersion++;
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- /// <summary>
- /// If this is NULL it&apos;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
deleted file mode 100644
index 2ea8e3b31..000000000
--- a/Jellyfin.Data/Entities/RatingSource.cs
+++ /dev/null
@@ -1,239 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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, 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
- {
- 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 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)
- {
- _Name = 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)
- {
- _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
deleted file mode 100644
index 3e2cf22db..000000000
--- a/Jellyfin.Data/Entities/Release.cs
+++ /dev/null
@@ -1,219 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-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 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
- {
- 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 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
deleted file mode 100644
index e5e7d03ab..000000000
--- a/Jellyfin.Data/Entities/Season.cs
+++ /dev/null
@@ -1,119 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</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="dateadded">The date the object was added.</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
- {
- int? value = _SeasonNumber;
- GetSeasonNumber(ref value);
- return _SeasonNumber = value;
- }
-
- set
- {
- int? oldValue = _SeasonNumber;
- SetSeasonNumber(oldValue, ref value);
- if (oldValue != value)
- {
- _SeasonNumber = value;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- [ForeignKey("SeasonMetadata_SeasonMetadata_Id")]
- public virtual ICollection<SeasonMetadata> SeasonMetadata { 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
deleted file mode 100644
index cce8cb125..000000000
--- a/Jellyfin.Data/Entities/SeasonMetadata.cs
+++ /dev/null
@@ -1,123 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- string oldValue = _Outline;
- SetOutline(oldValue, ref value);
- if (oldValue != value)
- {
- _Outline = value;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/Series.cs b/Jellyfin.Data/Entities/Series.cs
deleted file mode 100644
index 33c07ca61..000000000
--- a/Jellyfin.Data/Entities/Series.cs
+++ /dev/null
@@ -1,165 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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>
- /// 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="dateadded">The date the object was added.</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>
- /// <param name="dateadded">The date the object was added.</param>
- public static Series Create(Guid urlid, DateTime dateadded)
- {
- return new Series(urlid, dateadded);
- }
-
- /*************************************************************************
- * Properties
- *************************************************************************/
-
- /// <summary>
- /// Backing field for AirsDayOfWeek.
- /// </summary>
- protected DayOfWeek? _AirsDayOfWeek;
- /// <summary>
- /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before setting.
- /// </summary>
- partial void SetAirsDayOfWeek(DayOfWeek? oldValue, ref DayOfWeek? newValue);
- /// <summary>
- /// When provided in a partial class, allows value of AirsDayOfWeek to be changed before returning.
- /// </summary>
- partial void GetAirsDayOfWeek(ref DayOfWeek? result);
-
- public DayOfWeek? AirsDayOfWeek
- {
- get
- {
- DayOfWeek? value = _AirsDayOfWeek;
- GetAirsDayOfWeek(ref value);
- return _AirsDayOfWeek = value;
- }
-
- set
- {
- DayOfWeek? oldValue = _AirsDayOfWeek;
- SetAirsDayOfWeek(oldValue, ref value);
- if (oldValue != value)
- {
- _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)
- {
- _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;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- [ForeignKey("SeriesMetadata_SeriesMetadata_Id")]
- public virtual ICollection<SeriesMetadata> SeriesMetadata { 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
deleted file mode 100644
index 22be2a59b..000000000
--- a/Jellyfin.Data/Entities/SeriesMetadata.cs
+++ /dev/null
@@ -1,244 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- {
- 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
- {
- string oldValue = _Plot;
- SetPlot(oldValue, ref value);
- if (oldValue != value)
- {
- _Plot = 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)
- {
- _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;
- }
- }
- }
-
- /*************************************************************************
- * 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
deleted file mode 100644
index d52dd725a..000000000
--- a/Jellyfin.Data/Entities/Track.cs
+++ /dev/null
@@ -1,120 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations.Schema;
-
-namespace Jellyfin.Data.Entities
-{
- 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="dateadded">The date the object was added.</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="dateadded">The date the object was added.</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
- {
- int? oldValue = _TrackNumber;
- SetTrackNumber(oldValue, ref value);
- if (oldValue != value)
- {
- _TrackNumber = value;
- }
- }
- }
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
-
- [ForeignKey("Release_Releases_Id")]
- public virtual ICollection<Release> Releases { 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
deleted file mode 100644
index 710908eb8..000000000
--- a/Jellyfin.Data/Entities/TrackMetadata.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-#pragma warning disable CS1591
-
-using System;
-
-namespace Jellyfin.Data.Entities
-{
- 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()
- {
- 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>
- /// 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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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 (_track0 == null)
- {
- throw new ArgumentNullException(nameof(_track0));
- }
-
- _track0.TrackMetadata.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="dateadded">The date the object was added.</param>
- /// <param name="datemodified">The date the object was last modified.</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
- *************************************************************************/
-
- /*************************************************************************
- * Navigation properties
- *************************************************************************/
- }
-}
-
diff --git a/Jellyfin.Data/Entities/User.cs b/Jellyfin.Data/Entities/User.cs
index 8c720d85b..7ea1f4498 100644
--- a/Jellyfin.Data/Entities/User.cs
+++ b/Jellyfin.Data/Entities/User.cs
@@ -8,13 +8,14 @@ using System.Globalization;
using System.Linq;
using System.Text.Json.Serialization;
using Jellyfin.Data.Enums;
+using Jellyfin.Data.Interfaces;
namespace Jellyfin.Data.Entities
{
/// <summary>
/// An entity representing a user.
/// </summary>
- public partial class User : IHasPermissions, ISavingChanges
+ public partial class User : IHasPermissions, IHasConcurrencyToken
{
/// <summary>
/// The values being delimited here are Guids, so commas work as they do not appear in Guids.
diff --git a/Jellyfin.Data/ISavingChanges.cs b/Jellyfin.Data/ISavingChanges.cs
deleted file mode 100644
index f392dae6a..000000000
--- a/Jellyfin.Data/ISavingChanges.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma warning disable CS1591
-
-namespace Jellyfin.Data
-{
- public interface ISavingChanges
- {
- void OnSavingChanges();
- }
-}
diff --git a/Jellyfin.Data/Interfaces/IHasArtwork.cs b/Jellyfin.Data/Interfaces/IHasArtwork.cs
new file mode 100644
index 000000000..a4d9c54af
--- /dev/null
+++ b/Jellyfin.Data/Interfaces/IHasArtwork.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using Jellyfin.Data.Entities.Libraries;
+
+namespace Jellyfin.Data.Interfaces
+{
+ /// <summary>
+ /// An interface abstracting an entity that has artwork.
+ /// </summary>
+ public interface IHasArtwork
+ {
+ /// <summary>
+ /// Gets a collection containing this entity's artwork.
+ /// </summary>
+ ICollection<Artwork> Artwork { get; }
+ }
+}
diff --git a/Jellyfin.Data/Interfaces/IHasCompanies.cs b/Jellyfin.Data/Interfaces/IHasCompanies.cs
new file mode 100644
index 000000000..8f19ce04f
--- /dev/null
+++ b/Jellyfin.Data/Interfaces/IHasCompanies.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using Jellyfin.Data.Entities.Libraries;
+
+namespace Jellyfin.Data.Interfaces
+{
+ /// <summary>
+ /// An abstraction representing an entity that has companies.
+ /// </summary>
+ public interface IHasCompanies
+ {
+ /// <summary>
+ /// Gets a collection containing this entity's companies.
+ /// </summary>
+ ICollection<Company> Companies { get; }
+ }
+}
diff --git a/Jellyfin.Data/Interfaces/IHasConcurrencyToken.cs b/Jellyfin.Data/Interfaces/IHasConcurrencyToken.cs
new file mode 100644
index 000000000..2c4091493
--- /dev/null
+++ b/Jellyfin.Data/Interfaces/IHasConcurrencyToken.cs
@@ -0,0 +1,18 @@
+namespace Jellyfin.Data.Interfaces
+{
+ /// <summary>
+ /// An interface abstracting an entity that has a concurrency token.
+ /// </summary>
+ public interface IHasConcurrencyToken
+ {
+ /// <summary>
+ /// Gets the version of this row. Acts as a concurrency token.
+ /// </summary>
+ uint RowVersion { get; }
+
+ /// <summary>
+ /// Called when saving changes to this entity.
+ /// </summary>
+ void OnSavingChanges();
+ }
+}
diff --git a/Jellyfin.Data/IHasPermissions.cs b/Jellyfin.Data/Interfaces/IHasPermissions.cs
index 3be72259a..3be72259a 100644
--- a/Jellyfin.Data/IHasPermissions.cs
+++ b/Jellyfin.Data/Interfaces/IHasPermissions.cs
diff --git a/Jellyfin.Data/Interfaces/IHasReleases.cs b/Jellyfin.Data/Interfaces/IHasReleases.cs
new file mode 100644
index 000000000..3b615893e
--- /dev/null
+++ b/Jellyfin.Data/Interfaces/IHasReleases.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+using Jellyfin.Data.Entities.Libraries;
+
+namespace Jellyfin.Data.Interfaces
+{
+ /// <summary>
+ /// An abstraction representing an entity that has releases.
+ /// </summary>
+ public interface IHasReleases
+ {
+ /// <summary>
+ /// Gets a collection containing this entity's releases.
+ /// </summary>
+ ICollection<Release> Releases { get; }
+ }
+}
diff --git a/Jellyfin.Server.Implementations/JellyfinDb.cs b/Jellyfin.Server.Implementations/JellyfinDb.cs
index 7d864ebc6..08e4db388 100644
--- a/Jellyfin.Server.Implementations/JellyfinDb.cs
+++ b/Jellyfin.Server.Implementations/JellyfinDb.cs
@@ -2,8 +2,8 @@
using System;
using System.Linq;
-using Jellyfin.Data;
using Jellyfin.Data.Entities;
+using Jellyfin.Data.Interfaces;
using Microsoft.EntityFrameworkCore;
namespace Jellyfin.Server.Implementations
@@ -130,7 +130,7 @@ namespace Jellyfin.Server.Implementations
foreach (var saveEntity in ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified)
.Select(entry => entry.Entity)
- .OfType<ISavingChanges>())
+ .OfType<IHasConcurrencyToken>())
{
saveEntity.OnSavingChanges();
}
diff --git a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
index b2f861542..896f5f0b8 100644
--- a/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
+++ b/Jellyfin.Server/Extensions/ApiServiceCollectionExtensions.cs
@@ -135,14 +135,16 @@ namespace Jellyfin.Server.Extensions
/// </summary>
/// <param name="serviceCollection">The service collection.</param>
/// <param name="baseUrl">The base url for the API.</param>
- /// <param name="corsHosts">The configured cors hosts.</param>
+ /// <param name="pluginAssemblies">An IEnumberable containing all plugin assemblies with API controllers.</param>
+ /// /// <param name="corsHosts">The configured cors hosts.</param>
/// <returns>The MVC builder.</returns>
public static IMvcBuilder AddJellyfinApi(
this IServiceCollection serviceCollection,
string baseUrl,
+ IEnumerable<Assembly> pluginAssemblies,
string[] corsHosts)
{
- return serviceCollection
+ IMvcBuilder mvcBuilder = serviceCollection
.AddCors(options =>
{
options.AddPolicy(ServerCorsPolicy.DefaultPolicyName, new ServerCorsPolicy(corsHosts).Policy);
@@ -183,8 +185,14 @@ namespace Jellyfin.Server.Extensions
// From JsonDefaults.PascalCase
options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy;
- })
- .AddControllersAsServices();
+ });
+
+ foreach (Assembly pluginAssembly in pluginAssemblies)
+ {
+ mvcBuilder.AddApplicationPart(pluginAssembly);
+ }
+
+ return mvcBuilder.AddControllersAsServices();
}
/// <summary>
@@ -201,7 +209,7 @@ namespace Jellyfin.Server.Extensions
{
Type = SecuritySchemeType.ApiKey,
In = ParameterLocation.Header,
- Name = "X-Emby-Token",
+ Name = "X-Emby-Authorization",
Description = "API key header parameter"
});
diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs
index 966587a6a..63f704556 100644
--- a/Jellyfin.Server/Startup.cs
+++ b/Jellyfin.Server/Startup.cs
@@ -1,9 +1,12 @@
using System;
using System.ComponentModel;
+using System.Net.Http.Headers;
using Jellyfin.Api.TypeConverters;
using Jellyfin.Server.Extensions;
using Jellyfin.Server.Middleware;
using Jellyfin.Server.Models;
+using MediaBrowser.Common;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using Microsoft.AspNetCore.Builder;
@@ -20,14 +23,17 @@ namespace Jellyfin.Server
public class Startup
{
private readonly IServerConfigurationManager _serverConfigurationManager;
+ private readonly IApplicationHost _applicationHost;
/// <summary>
/// Initializes a new instance of the <see cref="Startup" /> class.
/// </summary>
/// <param name="serverConfigurationManager">The server configuration manager.</param>
- public Startup(IServerConfigurationManager serverConfigurationManager)
+ /// <param name="applicationHost">The application host.</param>
+ public Startup(IServerConfigurationManager serverConfigurationManager, IApplicationHost applicationHost)
{
_serverConfigurationManager = serverConfigurationManager;
+ _applicationHost = applicationHost;
}
/// <summary>
@@ -40,6 +46,7 @@ namespace Jellyfin.Server
services.AddHttpContextAccessor();
services.AddJellyfinApi(
_serverConfigurationManager.Configuration.BaseUrl.TrimStart('/'),
+ _applicationHost.GetApiPluginAssemblies(),
_serverConfigurationManager.Configuration.CorsHosts);
services.AddJellyfinApiSwagger();
@@ -48,7 +55,21 @@ namespace Jellyfin.Server
services.AddCustomAuthentication();
services.AddJellyfinApiAuthorization();
- services.AddHttpClient();
+
+ var productHeader = new ProductInfoHeaderValue(_applicationHost.Name.Replace(' ', '-'), _applicationHost.ApplicationVersionString);
+ services
+ .AddHttpClient(NamedClient.Default, c =>
+ {
+ c.DefaultRequestHeaders.UserAgent.Add(productHeader);
+ })
+ .ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler());
+
+ services.AddHttpClient(NamedClient.MusicBrainz, c =>
+ {
+ c.DefaultRequestHeaders.UserAgent.Add(productHeader);
+ c.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue($"({_applicationHost.ApplicationUserAgentAddress})"));
+ })
+ .ConfigurePrimaryHttpMessageHandler(x => new DefaultHttpClientHandler());
}
/// <summary>
diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs
index 7a76be722..849037ac4 100644
--- a/MediaBrowser.Common/IApplicationHost.cs
+++ b/MediaBrowser.Common/IApplicationHost.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
using System.Threading.Tasks;
using MediaBrowser.Common.Plugins;
using Microsoft.Extensions.DependencyInjection;
@@ -77,6 +78,12 @@ namespace MediaBrowser.Common
IReadOnlyList<IPlugin> Plugins { get; }
/// <summary>
+ /// Gets all plugin assemblies which implement a custom rest api.
+ /// </summary>
+ /// <returns>An <see cref="IEnumerable{Assembly}"/> containing the plugin assemblies.</returns>
+ IEnumerable<Assembly> GetApiPluginAssemblies();
+
+ /// <summary>
/// Notifies the pending restart.
/// </summary>
void NotifyPendingRestart();
diff --git a/MediaBrowser.Common/Json/Converters/JsonNullableStructConverter.cs b/MediaBrowser.Common/Json/Converters/JsonNullableStructConverter.cs
new file mode 100644
index 000000000..cffc41ba3
--- /dev/null
+++ b/MediaBrowser.Common/Json/Converters/JsonNullableStructConverter.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace MediaBrowser.Common.Json.Converters
+{
+ /// <summary>
+ /// Converts a nullable struct or value to/from JSON.
+ /// Required - some clients send an empty string.
+ /// </summary>
+ /// <typeparam name="T">The struct type.</typeparam>
+ public class JsonNullableStructConverter<T> : JsonConverter<T?>
+ where T : struct
+ {
+ private readonly JsonConverter<T?> _baseJsonConverter;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="JsonNullableStructConverter{T}"/> class.
+ /// </summary>
+ /// <param name="baseJsonConverter">The base json converter.</param>
+ public JsonNullableStructConverter(JsonConverter<T?> baseJsonConverter)
+ {
+ _baseJsonConverter = baseJsonConverter;
+ }
+
+ /// <inheritdoc />
+ public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
+ {
+ // Handle empty string.
+ if (reader.TokenType == JsonTokenType.String && ((reader.HasValueSequence && reader.ValueSequence.IsEmpty) || reader.ValueSpan.IsEmpty))
+ {
+ return null;
+ }
+
+ return _baseJsonConverter.Read(ref reader, typeToConvert, options);
+ }
+
+ /// <inheritdoc />
+ public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOptions options)
+ {
+ _baseJsonConverter.Write(writer, value, options);
+ }
+ }
+}
diff --git a/MediaBrowser.Common/Json/JsonDefaults.cs b/MediaBrowser.Common/Json/JsonDefaults.cs
index 9d30927db..5867cd4a0 100644
--- a/MediaBrowser.Common/Json/JsonDefaults.cs
+++ b/MediaBrowser.Common/Json/JsonDefaults.cs
@@ -29,8 +29,14 @@ namespace MediaBrowser.Common.Json
NumberHandling = JsonNumberHandling.AllowReadingFromString
};
+ // Get built-in converters for fallback converting.
+ var baseNullableInt32Converter = (JsonConverter<int?>)options.GetConverter(typeof(int?));
+ var baseNullableInt64Converter = (JsonConverter<long?>)options.GetConverter(typeof(long?));
+
options.Converters.Add(new JsonGuidConverter());
options.Converters.Add(new JsonStringEnumConverter());
+ options.Converters.Add(new JsonNullableStructConverter<int>(baseNullableInt32Converter));
+ options.Converters.Add(new JsonNullableStructConverter<long>(baseNullableInt64Converter));
return options;
}
diff --git a/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs b/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs
new file mode 100644
index 000000000..e189d6e70
--- /dev/null
+++ b/MediaBrowser.Common/Net/DefaultHttpClientHandler.cs
@@ -0,0 +1,20 @@
+using System.Net;
+using System.Net.Http;
+
+namespace MediaBrowser.Common.Net
+{
+ /// <summary>
+ /// Default http client handler.
+ /// </summary>
+ public class DefaultHttpClientHandler : HttpClientHandler
+ {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DefaultHttpClientHandler"/> class.
+ /// </summary>
+ public DefaultHttpClientHandler()
+ {
+ // TODO change to DecompressionMethods.All with .NET5
+ AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
+ }
+ }
+}
diff --git a/MediaBrowser.Common/Net/NamedClient.cs b/MediaBrowser.Common/Net/NamedClient.cs
new file mode 100644
index 000000000..0f6161c32
--- /dev/null
+++ b/MediaBrowser.Common/Net/NamedClient.cs
@@ -0,0 +1,18 @@
+namespace MediaBrowser.Common.Net
+{
+ /// <summary>
+ /// Registered http client names.
+ /// </summary>
+ public static class NamedClient
+ {
+ /// <summary>
+ /// Gets the value for the default named http client.
+ /// </summary>
+ public const string Default = nameof(Default);
+
+ /// <summary>
+ /// Gets the value for the MusicBrainz named http client.
+ /// </summary>
+ public const string MusicBrainz = nameof(MusicBrainz);
+ }
+}
diff --git a/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
new file mode 100644
index 000000000..959a2d771
--- /dev/null
+++ b/MediaBrowser.Controller/QuickConnect/IQuickConnect.cs
@@ -0,0 +1,87 @@
+using System;
+using MediaBrowser.Model.QuickConnect;
+
+namespace MediaBrowser.Controller.QuickConnect
+{
+ /// <summary>
+ /// Quick connect standard interface.
+ /// </summary>
+ public interface IQuickConnect
+ {
+ /// <summary>
+ /// Gets or sets the length of user facing codes.
+ /// </summary>
+ int CodeLength { get; set; }
+
+ /// <summary>
+ /// Gets or sets the name of internal access tokens.
+ /// </summary>
+ string TokenName { get; set; }
+
+ /// <summary>
+ /// Gets the current state of quick connect.
+ /// </summary>
+ QuickConnectState State { get; }
+
+ /// <summary>
+ /// Gets or sets the time (in minutes) before quick connect will automatically deactivate.
+ /// </summary>
+ int Timeout { get; set; }
+
+ /// <summary>
+ /// Assert that quick connect is currently active and throws an exception if it is not.
+ /// </summary>
+ void AssertActive();
+
+ /// <summary>
+ /// Temporarily activates quick connect for a short amount of time.
+ /// </summary>
+ void Activate();
+
+ /// <summary>
+ /// Changes the state of quick connect.
+ /// </summary>
+ /// <param name="newState">New state to change to.</param>
+ void SetState(QuickConnectState newState);
+
+ /// <summary>
+ /// Initiates a new quick connect request.
+ /// </summary>
+ /// <returns>A quick connect result with tokens to proceed or throws an exception if not active.</returns>
+ QuickConnectResult TryConnect();
+
+ /// <summary>
+ /// Checks the status of an individual request.
+ /// </summary>
+ /// <param name="secret">Unique secret identifier of the request.</param>
+ /// <returns>Quick connect result.</returns>
+ QuickConnectResult CheckRequestStatus(string secret);
+
+ /// <summary>
+ /// Authorizes a quick connect request to connect as the calling user.
+ /// </summary>
+ /// <param name="userId">User id.</param>
+ /// <param name="code">Identifying code for the request.</param>
+ /// <returns>A boolean indicating if the authorization completed successfully.</returns>
+ bool AuthorizeRequest(Guid userId, string code);
+
+ /// <summary>
+ /// Expire quick connect requests that are over the time limit. If <paramref name="expireAll"/> is true, all requests are unconditionally expired.
+ /// </summary>
+ /// <param name="expireAll">If true, all requests will be expired.</param>
+ void ExpireRequests(bool expireAll = false);
+
+ /// <summary>
+ /// Deletes all quick connect access tokens for the provided user.
+ /// </summary>
+ /// <param name="user">Guid of the user to delete tokens for.</param>
+ /// <returns>A count of the deleted tokens.</returns>
+ int DeleteAllDevices(Guid user);
+
+ /// <summary>
+ /// Generates a short code to display to the user to uniquely identify this request.
+ /// </summary>
+ /// <returns>A short, unique alphanumeric string.</returns>
+ string GenerateCode();
+ }
+}
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index 9237d21df..228b2331d 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -267,6 +267,14 @@ namespace MediaBrowser.Controller.Session
Task<AuthenticationResult> AuthenticateNewSession(AuthenticationRequest request);
/// <summary>
+ /// Authenticates a new session with quick connect.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <param name="token">Quick connect access token.</param>
+ /// <returns>Task{SessionInfo}.</returns>
+ Task<AuthenticationResult> AuthenticateQuickConnect(AuthenticationRequest request, string token);
+
+ /// <summary>
/// Creates the new session.
/// </summary>
/// <param name="request">The request.</param>
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index a743277d7..c4fb12e76 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -78,6 +78,11 @@ namespace MediaBrowser.Model.Configuration
/// <value><c>true</c> if this instance is port authorized; otherwise, <c>false</c>.</value>
public bool IsPortAuthorized { get; set; }
+ /// <summary>
+ /// Gets or sets if quick connect is available for use on this server.
+ /// </summary>
+ public bool QuickConnectAvailable { get; set; }
+
public bool AutoRunWebApp { get; set; }
public bool EnableRemoteAccess { get; set; }
@@ -304,6 +309,7 @@ namespace MediaBrowser.Model.Configuration
AutoRunWebApp = true;
EnableRemoteAccess = true;
+ QuickConnectAvailable = false;
EnableUPnP = false;
MinResumePct = 5;
diff --git a/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
new file mode 100644
index 000000000..0fa40b6a7
--- /dev/null
+++ b/MediaBrowser.Model/QuickConnect/QuickConnectResult.cs
@@ -0,0 +1,40 @@
+using System;
+
+namespace MediaBrowser.Model.QuickConnect
+{
+ /// <summary>
+ /// Stores the result of an incoming quick connect request.
+ /// </summary>
+ public class QuickConnectResult
+ {
+ /// <summary>
+ /// Gets a value indicating whether this request is authorized.
+ /// </summary>
+ public bool Authenticated => !string.IsNullOrEmpty(Authentication);
+
+ /// <summary>
+ /// Gets or sets the secret value used to uniquely identify this request. Can be used to retrieve authentication information.
+ /// </summary>
+ public string? Secret { get; set; }
+
+ /// <summary>
+ /// Gets or sets the user facing code used so the user can quickly differentiate this request from others.
+ /// </summary>
+ public string? Code { get; set; }
+
+ /// <summary>
+ /// Gets or sets the private access token.
+ /// </summary>
+ public string? Authentication { get; set; }
+
+ /// <summary>
+ /// Gets or sets an error message.
+ /// </summary>
+ public string? Error { get; set; }
+
+ /// <summary>
+ /// Gets or sets the DateTime that this request was created.
+ /// </summary>
+ public DateTime? DateAdded { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/QuickConnect/QuickConnectState.cs b/MediaBrowser.Model/QuickConnect/QuickConnectState.cs
new file mode 100644
index 000000000..f1074f25f
--- /dev/null
+++ b/MediaBrowser.Model/QuickConnect/QuickConnectState.cs
@@ -0,0 +1,23 @@
+namespace MediaBrowser.Model.QuickConnect
+{
+ /// <summary>
+ /// Quick connect state.
+ /// </summary>
+ public enum QuickConnectState
+ {
+ /// <summary>
+ /// This feature has not been opted into and is unavailable until the server administrator chooses to opt-in.
+ /// </summary>
+ Unavailable = 0,
+
+ /// <summary>
+ /// The feature is enabled for use on the server but is not currently accepting connection requests.
+ /// </summary>
+ Available = 1,
+
+ /// <summary>
+ /// The feature is actively accepting connection requests.
+ /// </summary>
+ Active = 2
+ }
+}