repo creation with initial code after cloning public repo

This commit is contained in:
2026-02-19 07:36:25 -05:00
commit 460884fea3
2860 changed files with 650825 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
<Project>
<!-- Sets defaults for all projects -->
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
<!-- Code Analyzers -->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<PackageReference Include="IDisposableAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="SerilogAnalyzer" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="All" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" />
</ItemGroup>
</Project>
@@ -0,0 +1,9 @@
; Shipped analyzer releases
; https://github.com/dotnet/roslyn/blob/main/src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md
## Release 1.0
### New Rules
Rule ID | Category | Severity | Notes
--------|----------|----------|-------
JF0001 | Usage | Warning | Async-created IAsyncDisposable objects should use 'await using'
@@ -0,0 +1,82 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Jellyfin.CodeAnalysis;
/// <summary>
/// Analyzer to detect sync disposal of async-created IAsyncDisposable objects.
/// </summary>
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class AsyncDisposalPatternAnalyzer : DiagnosticAnalyzer
{
/// <summary>
/// Diagnostic descriptor for sync disposal of async-created IAsyncDisposable objects.
/// </summary>
public static readonly DiagnosticDescriptor AsyncDisposableSyncDisposal = new(
id: "JF0001",
title: "Async-created IAsyncDisposable objects should use 'await using'",
messageFormat: "Using 'using' with async-created IAsyncDisposable object '{0}'. Use 'await using' instead to prevent resource leaks.",
category: "Usage",
defaultSeverity: DiagnosticSeverity.Error,
isEnabledByDefault: true,
description: "Objects that implement IAsyncDisposable and are created using 'await' should be disposed using 'await using' to prevent resource leaks.");
/// <inheritdoc/>
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => [AsyncDisposableSyncDisposal];
/// <inheritdoc/>
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeUsingStatement, SyntaxKind.UsingStatement);
}
private static void AnalyzeUsingStatement(SyntaxNodeAnalysisContext context)
{
var usingStatement = (UsingStatementSyntax)context.Node;
// Skip 'await using' statements
if (usingStatement.AwaitKeyword.IsKind(SyntaxKind.AwaitKeyword))
{
return;
}
// Check if there's a variable declaration
if (usingStatement.Declaration?.Variables is null)
{
return;
}
foreach (var variable in usingStatement.Declaration.Variables)
{
if (variable.Initializer?.Value is AwaitExpressionSyntax awaitExpression)
{
var typeInfo = context.SemanticModel.GetTypeInfo(awaitExpression);
var type = typeInfo.Type;
if (type is not null && ImplementsIAsyncDisposable(type))
{
var diagnostic = Diagnostic.Create(
AsyncDisposableSyncDisposal,
usingStatement.GetLocation(),
type.Name);
context.ReportDiagnostic(diagnostic);
}
}
}
}
private static bool ImplementsIAsyncDisposable(ITypeSymbol type)
{
return type.AllInterfaces.Any(i =>
string.Equals(i.Name, "IAsyncDisposable", StringComparison.Ordinal)
&& string.Equals(i.ContainingNamespace?.ToDisplayString(), "System", StringComparison.Ordinal));
}
}
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<IncludeBuildOutput>false</IncludeBuildOutput>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" PrivateAssets="all" />
</ItemGroup>
</Project>
@@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
@@ -0,0 +1,22 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("Jellyfin.CodeAnalysis")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")]
[assembly: System.Reflection.AssemblyProductAttribute("Jellyfin.CodeAnalysis")]
[assembly: System.Reflection.AssemblyTitleAttribute("Jellyfin.CodeAnalysis")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
// Generated by the MSBuild WriteCodeFragment class.
@@ -0,0 +1 @@
307f6dc34c1d407ded7796905c4f301fa25bfd699be03d46bab15e6b61d5ed72
@@ -0,0 +1,26 @@
is_global = true
build_property.TargetFramework = netstandard2.0
build_property.TargetFramework = netstandard2.0
build_property.TargetPlatformMinVersion = 7.0
build_property.TargetPlatformMinVersion = 7.0
build_property.UsingMicrosoftNETSdkWeb =
build_property.UsingMicrosoftNETSdkWeb =
build_property.ProjectTypeGuids =
build_property.ProjectTypeGuids =
build_property.InvariantGlobalization =
build_property.InvariantGlobalization =
build_property.PlatformNeutralAssembly =
build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules = true
build_property.EnforceExtendedAnalyzerRules = true
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.TargetFrameworkIdentifier = .NETStandard
build_property.TargetFrameworkVersion = v2.0
build_property.RootNamespace = Jellyfin.CodeAnalysis
build_property.ProjectDir = /srv/common_drive/Projects/pgsql-jellyfin/src/Jellyfin.CodeAnalysis/
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
build_property.EffectiveAnalysisLevelStyle =
build_property.EnableCodeStyleSeverity =
@@ -0,0 +1,205 @@
{
"format": 1,
"restore": {
"/srv/common_drive/Projects/pgsql-jellyfin/src/Jellyfin.CodeAnalysis/Jellyfin.CodeAnalysis.csproj": {}
},
"projects": {
"/srv/common_drive/Projects/pgsql-jellyfin/src/Jellyfin.CodeAnalysis/Jellyfin.CodeAnalysis.csproj": {
"version": "1.0.0",
"restore": {
"projectUniqueName": "/srv/common_drive/Projects/pgsql-jellyfin/src/Jellyfin.CodeAnalysis/Jellyfin.CodeAnalysis.csproj",
"projectName": "Jellyfin.CodeAnalysis",
"projectPath": "/srv/common_drive/Projects/pgsql-jellyfin/src/Jellyfin.CodeAnalysis/Jellyfin.CodeAnalysis.csproj",
"packagesPath": "/home/wjones/.nuget/packages/",
"outputPath": "/srv/common_drive/Projects/pgsql-jellyfin/src/Jellyfin.CodeAnalysis/obj/",
"projectStyle": "PackageReference",
"centralPackageVersionsManagementEnabled": true,
"configFilePaths": [
"/srv/common_drive/Projects/pgsql-jellyfin/nuget.config",
"/home/wjones/.nuget/NuGet/NuGet.Config"
],
"originalTargetFrameworks": [
"netstandard2.0"
],
"sources": {
"/usr/lib/dotnet/library-packs": {},
"https://api.nuget.org/v3/index.json": {}
},
"frameworks": {
"netstandard2.0": {
"targetAlias": "netstandard2.0",
"projectReferences": {}
}
},
"warningProperties": {
"allWarningsAsErrors": true,
"warnAsError": [
"NU1605"
],
"warnNotAsError": [
"NU1902",
"NU1903"
]
},
"restoreAuditProperties": {
"enableAudit": "true",
"auditLevel": "low",
"auditMode": "direct"
},
"SdkAnalysisLevel": "10.0.100"
},
"frameworks": {
"netstandard2.0": {
"targetAlias": "netstandard2.0",
"dependencies": {
"IDisposableAnalyzers": {
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
"suppressParent": "All",
"target": "Package",
"version": "[4.0.8, )",
"versionCentrallyManaged": true
},
"Microsoft.CodeAnalysis.Analyzers": {
"suppressParent": "All",
"target": "Package",
"version": "[3.11.0, )",
"versionCentrallyManaged": true
},
"Microsoft.CodeAnalysis.BannedApiAnalyzers": {
"include": "Runtime, Build, Native, ContentFiles, Analyzers",
"suppressParent": "All",
"target": "Package",
"version": "[4.14.0, )",
"versionCentrallyManaged": true
},
"Microsoft.CodeAnalysis.CSharp": {
"suppressParent": "All",
"target": "Package",
"version": "[5.0.0, )",
"versionCentrallyManaged": true
},
"NETStandard.Library": {
"suppressParent": "All",
"target": "Package",
"version": "[2.0.3, )",
"autoReferenced": true
},
"SerilogAnalyzer": {
"suppressParent": "All",
"target": "Package",
"version": "[0.15.0, )",
"versionCentrallyManaged": true
},
"SmartAnalyzers.MultithreadingAnalyzer": {
"suppressParent": "All",
"target": "Package",
"version": "[1.1.31, )",
"versionCentrallyManaged": true
},
"StyleCop.Analyzers": {
"suppressParent": "All",
"target": "Package",
"version": "[1.2.0-beta.556, )",
"versionCentrallyManaged": true
}
},
"centralPackageVersions": {
"AsyncKeyedLock": "8.0.2",
"AutoFixture": "4.18.1",
"AutoFixture.AutoMoq": "4.18.1",
"AutoFixture.Xunit2": "4.18.1",
"BDInfo": "0.8.0",
"BitFaster.Caching": "2.5.4",
"BlurHashSharp": "1.4.0-pre.1",
"BlurHashSharp.SkiaSharp": "1.4.0-pre.1",
"CommandLineParser": "2.9.1",
"coverlet.collector": "8.0.0",
"Diacritics": "4.1.4",
"DiscUtils.Udf": "0.16.13",
"DotNet.Glob": "3.1.3",
"FsCheck.Xunit": "3.3.2",
"HarfBuzzSharp.NativeAssets.Linux": "8.3.1.1",
"ICU4N.Transliterator": "60.1.0-alpha.356",
"IDisposableAnalyzers": "4.0.8",
"Ignore": "0.2.1",
"Jellyfin.XmlTv": "10.8.0",
"libse": "4.0.12",
"LrcParser": "2025.623.0",
"MetaBrainz.MusicBrainz": "8.0.1",
"Microsoft.AspNetCore.Authorization": "10.0.3",
"Microsoft.AspNetCore.Mvc.Testing": "10.0.3",
"Microsoft.CodeAnalysis.Analyzers": "3.11.0",
"Microsoft.CodeAnalysis.BannedApiAnalyzers": "4.14.0",
"Microsoft.CodeAnalysis.Common": "5.0.0",
"Microsoft.CodeAnalysis.CSharp": "5.0.0",
"Microsoft.Data.Sqlite": "10.0.3",
"Microsoft.EntityFrameworkCore.Design": "10.0.3",
"Microsoft.EntityFrameworkCore.Relational": "10.0.3",
"Microsoft.EntityFrameworkCore.Sqlite": "10.0.3",
"Microsoft.EntityFrameworkCore.Tools": "10.0.3",
"Microsoft.Extensions.Caching.Abstractions": "10.0.3",
"Microsoft.Extensions.Caching.Memory": "10.0.3",
"Microsoft.Extensions.Configuration.Abstractions": "10.0.3",
"Microsoft.Extensions.Configuration.Binder": "10.0.3",
"Microsoft.Extensions.DependencyInjection": "10.0.3",
"Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore": "10.0.3",
"Microsoft.Extensions.Hosting.Abstractions": "10.0.3",
"Microsoft.Extensions.Http": "10.0.3",
"Microsoft.Extensions.Logging": "10.0.3",
"Microsoft.Extensions.Options": "10.0.3",
"Microsoft.NET.Test.Sdk": "18.0.1",
"MimeTypes": "2.5.2",
"Moq": "4.18.4",
"Morestachio": "5.0.1.631",
"NEbml": "1.1.0.5",
"Newtonsoft.Json": "13.0.4",
"PlaylistsNET": "1.4.1",
"Polly": "8.6.5",
"prometheus-net": "8.2.1",
"prometheus-net.AspNetCore": "8.2.1",
"prometheus-net.DotNetRuntime": "4.4.1",
"Serilog.AspNetCore": "10.0.0",
"Serilog.Enrichers.Thread": "4.0.0",
"Serilog.Expressions": "5.0.0",
"Serilog.Settings.Configuration": "10.0.0",
"Serilog.Sinks.Async": "2.1.0",
"Serilog.Sinks.Console": "6.1.1",
"Serilog.Sinks.File": "7.0.0",
"Serilog.Sinks.Graylog": "3.1.1",
"SerilogAnalyzer": "0.15.0",
"SharpFuzz": "2.2.0",
"SkiaSharp": "[3.116.1]",
"SkiaSharp.HarfBuzz": "[3.116.1]",
"SkiaSharp.NativeAssets.Linux": "[3.116.1]",
"SmartAnalyzers.MultithreadingAnalyzer": "1.1.31",
"StyleCop.Analyzers": "1.2.0-beta.556",
"Svg.Skia": "3.4.1",
"Swashbuckle.AspNetCore": "7.3.2",
"Swashbuckle.AspNetCore.ReDoc": "6.9.0",
"System.Text.Json": "10.0.3",
"TagLibSharp": "2.3.0",
"TMDbLib": "2.3.0",
"UTF.Unknown": "2.6.0",
"xunit": "2.9.3",
"Xunit.Priority": "1.1.6",
"xunit.runner.visualstudio": "2.8.2",
"Xunit.SkippableFact": "1.5.61",
"z440.atl.core": "7.11.0"
},
"imports": [
"net461",
"net462",
"net47",
"net471",
"net472",
"net48",
"net481"
],
"assetTargetFallback": true,
"warn": true,
"runtimeIdentifierGraphPath": "/usr/lib/dotnet/sdk/10.0.103/RuntimeIdentifierGraph.json"
}
}
}
}
}
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">$(MSBuildThisFileDirectory)project.assets.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">/home/wjones/.nuget/packages/</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
</PropertyGroup>
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<SourceRoot Include="/home/wjones/.nuget/packages/" />
</ItemGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.analyzers/3.11.0/buildTransitive/Microsoft.CodeAnalysis.Analyzers.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.analyzers/3.11.0/buildTransitive/Microsoft.CodeAnalysis.Analyzers.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.props')" />
</ImportGroup>
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<PkgStyleCop_Analyzers_Unstable Condition=" '$(PkgStyleCop_Analyzers_Unstable)' == '' ">/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556</PkgStyleCop_Analyzers_Unstable>
<PkgSmartAnalyzers_MultithreadingAnalyzer Condition=" '$(PkgSmartAnalyzers_MultithreadingAnalyzer)' == '' ">/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31</PkgSmartAnalyzers_MultithreadingAnalyzer>
<PkgSerilogAnalyzer Condition=" '$(PkgSerilogAnalyzer)' == '' ">/home/wjones/.nuget/packages/seriloganalyzer/0.15.0</PkgSerilogAnalyzer>
<PkgMicrosoft_CodeAnalysis_Analyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_Analyzers)' == '' ">/home/wjones/.nuget/packages/microsoft.codeanalysis.analyzers/3.11.0</PkgMicrosoft_CodeAnalysis_Analyzers>
<PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers Condition=" '$(PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers)' == '' ">/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0</PkgMicrosoft_CodeAnalysis_BannedApiAnalyzers>
<PkgIDisposableAnalyzers Condition=" '$(PkgIDisposableAnalyzers)' == '' ">/home/wjones/.nuget/packages/idisposableanalyzers/4.0.8</PkgIDisposableAnalyzers>
</PropertyGroup>
</Project>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)netstandard.library/2.0.3/build/netstandard2.0/NETStandard.Library.targets" Condition="Exists('$(NuGetPackageRoot)netstandard.library/2.0.3/build/netstandard2.0/NETStandard.Library.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.analyzers/3.11.0/buildTransitive/Microsoft.CodeAnalysis.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.analyzers/3.11.0/buildTransitive/Microsoft.CodeAnalysis.Analyzers.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.codeanalysis.bannedapianalyzers/4.14.0/buildTransitive/Microsoft.CodeAnalysis.BannedApiAnalyzers.targets')" />
</ImportGroup>
</Project>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,28 @@
{
"version": 2,
"dgSpecHash": "dMXfECU2tHc=",
"success": true,
"projectFilePath": "/srv/common_drive/Projects/pgsql-jellyfin/src/Jellyfin.CodeAnalysis/Jellyfin.CodeAnalysis.csproj",
"expectedPackageFiles": [
"/home/wjones/.nuget/packages/idisposableanalyzers/4.0.8/idisposableanalyzers.4.0.8.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.codeanalysis.analyzers/3.11.0/microsoft.codeanalysis.analyzers.3.11.0.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.codeanalysis.bannedapianalyzers/4.14.0/microsoft.codeanalysis.bannedapianalyzers.4.14.0.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.codeanalysis.common/5.0.0/microsoft.codeanalysis.common.5.0.0.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.codeanalysis.csharp/5.0.0/microsoft.codeanalysis.csharp.5.0.0.nupkg.sha512",
"/home/wjones/.nuget/packages/microsoft.netcore.platforms/1.1.0/microsoft.netcore.platforms.1.1.0.nupkg.sha512",
"/home/wjones/.nuget/packages/netstandard.library/2.0.3/netstandard.library.2.0.3.nupkg.sha512",
"/home/wjones/.nuget/packages/seriloganalyzer/0.15.0/seriloganalyzer.0.15.0.nupkg.sha512",
"/home/wjones/.nuget/packages/smartanalyzers.multithreadinganalyzer/1.1.31/smartanalyzers.multithreadinganalyzer.1.1.31.nupkg.sha512",
"/home/wjones/.nuget/packages/stylecop.analyzers/1.2.0-beta.556/stylecop.analyzers.1.2.0-beta.556.nupkg.sha512",
"/home/wjones/.nuget/packages/stylecop.analyzers.unstable/1.2.0.556/stylecop.analyzers.unstable.1.2.0.556.nupkg.sha512",
"/home/wjones/.nuget/packages/system.buffers/4.6.0/system.buffers.4.6.0.nupkg.sha512",
"/home/wjones/.nuget/packages/system.collections.immutable/9.0.0/system.collections.immutable.9.0.0.nupkg.sha512",
"/home/wjones/.nuget/packages/system.memory/4.6.0/system.memory.4.6.0.nupkg.sha512",
"/home/wjones/.nuget/packages/system.numerics.vectors/4.6.0/system.numerics.vectors.4.6.0.nupkg.sha512",
"/home/wjones/.nuget/packages/system.reflection.metadata/9.0.0/system.reflection.metadata.9.0.0.nupkg.sha512",
"/home/wjones/.nuget/packages/system.runtime.compilerservices.unsafe/6.1.0/system.runtime.compilerservices.unsafe.6.1.0.nupkg.sha512",
"/home/wjones/.nuget/packages/system.text.encoding.codepages/8.0.0/system.text.encoding.codepages.8.0.0.nupkg.sha512",
"/home/wjones/.nuget/packages/system.threading.tasks.extensions/4.6.0/system.threading.tasks.extensions.4.6.0.nupkg.sha512"
],
"logs": []
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
17714532103300000
@@ -0,0 +1 @@
17715044209300000
@@ -0,0 +1,19 @@
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.DbConfiguration;
/// <summary>
/// The custom value option for custom database providers.
/// </summary>
public class CustomDatabaseOption
{
/// <summary>
/// Gets or sets the key of the value.
/// </summary>
public required string Key { get; set; }
/// <summary>
/// Gets or sets the value.
/// </summary>
public required string Value { get; set; }
}
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Jellyfin.Database.Implementations.DbConfiguration;
/// <summary>
/// Defines the options for a custom database connector.
/// </summary>
public class CustomDatabaseOptions
{
/// <summary>
/// Gets or sets the Plugin name to search for database providers.
/// </summary>
public required string PluginName { get; set; }
/// <summary>
/// Gets or sets the plugin assembly to search for providers.
/// </summary>
public required string PluginAssembly { get; set; }
/// <summary>
/// Gets or sets the connection string for the custom database provider.
/// </summary>
public required string ConnectionString { get; set; }
/// <summary>
/// Gets or sets the list of extra options for the custom provider.
/// </summary>
#pragma warning disable CA2227 // Collection properties should be read only
public Collection<CustomDatabaseOption> Options { get; set; } = [];
#pragma warning restore CA2227 // Collection properties should be read only
}
@@ -0,0 +1,25 @@
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.DbConfiguration;
/// <summary>
/// Options to configure jellyfins managed database.
/// </summary>
public class DatabaseConfigurationOptions
{
/// <summary>
/// Gets or Sets the type of database jellyfin should use.
/// </summary>
public required string DatabaseType { get; set; }
/// <summary>
/// Gets or sets the options required to use a custom database provider.
/// </summary>
public CustomDatabaseOptions? CustomProviderOptions { get; set; }
/// <summary>
/// Gets or Sets the kind of locking behavior jellyfin should perform. Possible options are "NoLock", "Pessimistic", "Optimistic".
/// Defaults to "NoLock".
/// </summary>
public DatabaseLockingBehaviorTypes LockingBehavior { get; set; }
}
@@ -0,0 +1,22 @@
namespace Jellyfin.Database.Implementations.DbConfiguration;
/// <summary>
/// Defines all possible methods for locking database access for concurrent queries.
/// </summary>
public enum DatabaseLockingBehaviorTypes
{
/// <summary>
/// Defines that no explicit application level locking for reads and writes should be done and only provider specific locking should be relied on.
/// </summary>
NoLock = 0,
/// <summary>
/// Defines a behavior that always blocks all reads while any one write is done.
/// </summary>
Pessimistic = 1,
/// <summary>
/// Defines that all writes should be attempted and when fail should be retried.
/// </summary>
Optimistic = 2
}
@@ -0,0 +1,62 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Xml.Serialization;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing a user's access schedule.
/// </summary>
public class AccessSchedule
{
/// <summary>
/// Initializes a new instance of the <see cref="AccessSchedule"/> class.
/// </summary>
/// <param name="dayOfWeek">The day of the week.</param>
/// <param name="startHour">The start hour.</param>
/// <param name="endHour">The end hour.</param>
/// <param name="userId">The associated user's id.</param>
public AccessSchedule(DynamicDayOfWeek dayOfWeek, double startHour, double endHour, Guid userId)
{
UserId = userId;
DayOfWeek = dayOfWeek;
StartHour = startHour;
EndHour = endHour;
}
/// <summary>
/// Gets the id of this instance.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[XmlIgnore]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets the id of the associated user.
/// </summary>
[XmlIgnore]
public Guid UserId { get; private set; }
/// <summary>
/// Gets or sets the day of week.
/// </summary>
/// <value>The day of week.</value>
public DynamicDayOfWeek DayOfWeek { get; set; }
/// <summary>
/// Gets or sets the start hour.
/// </summary>
/// <value>The start hour.</value>
public double StartHour { get; set; }
/// <summary>
/// Gets or sets the end hour.
/// </summary>
/// <value>The end hour.</value>
public double EndHour { get; set; }
}
}
@@ -0,0 +1,123 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity referencing an activity log entry.
/// </summary>
public class ActivityLog : IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="ActivityLog"/> class.
/// Public constructor with required data.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="type">The type.</param>
/// <param name="userId">The user id.</param>
public ActivityLog(string name, string type, Guid userId)
{
ArgumentException.ThrowIfNullOrEmpty(name);
ArgumentException.ThrowIfNullOrEmpty(type);
Name = name;
Type = type;
UserId = userId;
DateCreated = DateTime.UtcNow;
LogSeverity = LogLevel.Information;
}
/// <summary>
/// Gets the identity of this instance.
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <remarks>
/// Required, Max length = 512.
/// </remarks>
[MaxLength(512)]
[StringLength(512)]
public string Name { get; set; }
/// <summary>
/// Gets or sets the overview.
/// </summary>
/// <remarks>
/// Max length = 512.
/// </remarks>
[MaxLength(512)]
[StringLength(512)]
public string? Overview { get; set; }
/// <summary>
/// Gets or sets the short overview.
/// </summary>
/// <remarks>
/// Max length = 512.
/// </remarks>
[MaxLength(512)]
[StringLength(512)]
public string? ShortOverview { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <remarks>
/// Required, Max length = 256.
/// </remarks>
[MaxLength(256)]
[StringLength(256)]
public string Type { get; set; }
/// <summary>
/// Gets or sets the user id.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the item id.
/// </summary>
/// <remarks>
/// Max length = 256.
/// </remarks>
[MaxLength(256)]
[StringLength(256)]
public string? ItemId { get; set; }
/// <summary>
/// Gets or sets the date created. This should be in UTC.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public DateTime DateCreated { get; set; }
/// <summary>
/// Gets or sets the log severity. Default is <see cref="LogLevel.Trace"/>.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public LogLevel LogSeverity { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,29 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Represents the relational information for an <see cref="BaseItemEntity"/>.
/// </summary>
public class AncestorId
{
/// <summary>
/// Gets or Sets the AncestorId.
/// </summary>
public required Guid ParentItemId { get; set; }
/// <summary>
/// Gets or Sets the related BaseItem.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets the ParentItem.
/// </summary>
public required BaseItemEntity ParentItem { get; set; }
/// <summary>
/// Gets or Sets the Child item.
/// </summary>
public required BaseItemEntity Item { get; set; }
}
@@ -0,0 +1,49 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Provides information about an Attachment to an <see cref="BaseItemEntity"/>.
/// </summary>
public class AttachmentStreamInfo
{
/// <summary>
/// Gets or Sets the <see cref="BaseItemEntity"/> reference.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets the <see cref="BaseItemEntity"/> reference.
/// </summary>
public required BaseItemEntity Item { get; set; }
/// <summary>
/// Gets or Sets the index within the source file.
/// </summary>
public required int Index { get; set; }
/// <summary>
/// Gets or Sets the codec of the attachment.
/// </summary>
public string? Codec { get; set; }
/// <summary>
/// Gets or Sets the codec tag of the attachment.
/// </summary>
public string? CodecTag { get; set; }
/// <summary>
/// Gets or Sets the comment of the attachment.
/// </summary>
public string? Comment { get; set; }
/// <summary>
/// Gets or Sets the filename of the attachment.
/// </summary>
public string? Filename { get; set; }
/// <summary>
/// Gets or Sets the attachments mimetype.
/// </summary>
public string? MimeType { get; set; }
}
@@ -0,0 +1,190 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#pragma warning disable CA2227 // Collection properties should be read only
using System;
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.Entities;
public class BaseItemEntity
{
public required Guid Id { get; set; }
public required string Type { get; set; }
public string? Data { get; set; }
public string? Path { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public Guid? ChannelId { get; set; }
public bool IsMovie { get; set; }
public float? CommunityRating { get; set; }
public string? CustomRating { get; set; }
public int? IndexNumber { get; set; }
public bool IsLocked { get; set; }
public string? Name { get; set; }
public string? OfficialRating { get; set; }
public string? MediaType { get; set; }
public string? Overview { get; set; }
public int? ParentIndexNumber { get; set; }
public DateTime? PremiereDate { get; set; }
public int? ProductionYear { get; set; }
public string? Genres { get; set; }
public string? SortName { get; set; }
public string? ForcedSortName { get; set; }
public long? RunTimeTicks { get; set; }
public DateTime? DateCreated { get; set; }
public DateTime? DateModified { get; set; }
public bool IsSeries { get; set; }
public string? EpisodeTitle { get; set; }
public bool IsRepeat { get; set; }
public string? PreferredMetadataLanguage { get; set; }
public string? PreferredMetadataCountryCode { get; set; }
public DateTime? DateLastRefreshed { get; set; }
public DateTime? DateLastSaved { get; set; }
public bool IsInMixedFolder { get; set; }
public string? Studios { get; set; }
public string? ExternalServiceId { get; set; }
public string? Tags { get; set; }
public bool IsFolder { get; set; }
public int? InheritedParentalRatingValue { get; set; }
public int? InheritedParentalRatingSubValue { get; set; }
public string? UnratedType { get; set; }
public float? CriticRating { get; set; }
public string? CleanName { get; set; }
public string? PresentationUniqueKey { get; set; }
public string? OriginalTitle { get; set; }
public string? PrimaryVersionId { get; set; }
public DateTime? DateLastMediaAdded { get; set; }
public string? Album { get; set; }
public float? LUFS { get; set; }
public float? NormalizationGain { get; set; }
public bool IsVirtualItem { get; set; }
public string? SeriesName { get; set; }
public string? SeasonName { get; set; }
public string? ExternalSeriesId { get; set; }
public string? Tagline { get; set; }
public string? ProductionLocations { get; set; }
public string? ExtraIds { get; set; }
public int? TotalBitrate { get; set; }
public BaseItemExtraType? ExtraType { get; set; }
public string? Artists { get; set; }
public string? AlbumArtists { get; set; }
public string? ExternalId { get; set; }
public string? SeriesPresentationUniqueKey { get; set; }
public string? ShowId { get; set; }
public string? OwnerId { get; set; }
public int? Width { get; set; }
public int? Height { get; set; }
public long? Size { get; set; }
public ProgramAudioEntity? Audio { get; set; }
public Guid? ParentId { get; set; }
public BaseItemEntity? DirectParent { get; set; }
public Guid? TopParentId { get; set; }
public Guid? SeasonId { get; set; }
public Guid? SeriesId { get; set; }
public ICollection<PeopleBaseItemMap>? Peoples { get; set; }
public ICollection<UserData>? UserData { get; set; }
public ICollection<ItemValueMap>? ItemValues { get; set; }
public ICollection<MediaStreamInfo>? MediaStreams { get; set; }
public ICollection<Chapter>? Chapters { get; set; }
public ICollection<BaseItemProvider>? Provider { get; set; }
public ICollection<AncestorId>? Parents { get; set; }
public ICollection<AncestorId>? Children { get; set; }
public ICollection<BaseItemEntity>? DirectChildren { get; set; }
public ICollection<BaseItemMetadataField>? LockedFields { get; set; }
public ICollection<BaseItemTrailerType>? TrailerTypes { get; set; }
public ICollection<BaseItemImageInfo>? Images { get; set; }
// those are references to __LOCAL__ ids not DB ids ... TODO: Bring the whole folder structure into the DB
// public ICollection<BaseItemEntity>? SeriesEpisodes { get; set; }
// public BaseItemEntity? Series { get; set; }
// public BaseItemEntity? Season { get; set; }
// public BaseItemEntity? Parent { get; set; }
// public ICollection<BaseItemEntity>? DirectChildren { get; set; }
// public BaseItemEntity? TopParent { get; set; }
// public ICollection<BaseItemEntity>? AllChildren { get; set; }
// public ICollection<BaseItemEntity>? SeasonEpisodes { get; set; }
}
@@ -0,0 +1,18 @@
#pragma warning disable CS1591
namespace Jellyfin.Database.Implementations.Entities;
public enum BaseItemExtraType
{
Unknown = 0,
Clip = 1,
Trailer = 2,
BehindTheScenes = 3,
DeletedScene = 4,
Interview = 5,
Scene = 6,
Sample = 7,
ThemeSong = 8,
ThemeVideo = 9,
Featurette = 10,
Short = 11
}
@@ -0,0 +1,58 @@
#pragma warning disable CA2227
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Enum TrailerTypes.
/// </summary>
public class BaseItemImageInfo
{
/// <summary>
/// Gets or Sets.
/// </summary>
public required Guid Id { get; set; }
/// <summary>
/// Gets or Sets the path to the original image.
/// </summary>
public required string Path { get; set; }
/// <summary>
/// Gets or Sets the time the image was last modified.
/// </summary>
public DateTime? DateModified { get; set; }
/// <summary>
/// Gets or Sets the imagetype.
/// </summary>
public ImageInfoImageType ImageType { get; set; }
/// <summary>
/// Gets or Sets the width of the original image.
/// </summary>
public int Width { get; set; }
/// <summary>
/// Gets or Sets the height of the original image.
/// </summary>
public int Height { get; set; }
#pragma warning disable CA1819 // Properties should not return arrays
/// <summary>
/// Gets or Sets the blurhash.
/// </summary>
public byte[]? Blurhash { get; set; }
#pragma warning restore CA1819
/// <summary>
/// Gets or Sets the reference id to the BaseItem.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets the referenced Item.
/// </summary>
public required BaseItemEntity Item { get; set; }
}
@@ -0,0 +1,24 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Enum MetadataFields.
/// </summary>
public class BaseItemMetadataField
{
/// <summary>
/// Gets or Sets Numerical ID of this enumerable.
/// </summary>
public required int Id { get; set; }
/// <summary>
/// Gets or Sets all referenced <see cref="BaseItemEntity"/>.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets all referenced <see cref="BaseItemEntity"/>.
/// </summary>
public required BaseItemEntity Item { get; set; }
}
@@ -0,0 +1,29 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Represents a Key-Value relation of an BaseItem's provider.
/// </summary>
public class BaseItemProvider
{
/// <summary>
/// Gets or Sets the reference ItemId.
/// </summary>
public Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets the reference BaseItem.
/// </summary>
public required BaseItemEntity Item { get; set; }
/// <summary>
/// Gets or Sets the ProvidersId.
/// </summary>
public required string ProviderId { get; set; }
/// <summary>
/// Gets or Sets the Providers Value.
/// </summary>
public required string ProviderValue { get; set; }
}
@@ -0,0 +1,24 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Enum TrailerTypes.
/// </summary>
public class BaseItemTrailerType
{
/// <summary>
/// Gets or Sets Numerical ID of this enumerable.
/// </summary>
public required int Id { get; set; }
/// <summary>
/// Gets or Sets all referenced <see cref="BaseItemEntity"/>.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets all referenced <see cref="BaseItemEntity"/>.
/// </summary>
public required BaseItemEntity Item { get; set; }
}
@@ -0,0 +1,44 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// The Chapter entity.
/// </summary>
public class Chapter
{
/// <summary>
/// Gets or Sets the <see cref="BaseItemEntity"/> reference id.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets the <see cref="BaseItemEntity"/> reference.
/// </summary>
public required BaseItemEntity Item { get; set; }
/// <summary>
/// Gets or Sets the chapters index in Item.
/// </summary>
public required int ChapterIndex { get; set; }
/// <summary>
/// Gets or Sets the position within the source file.
/// </summary>
public required long StartPositionTicks { get; set; }
/// <summary>
/// Gets or Sets the common name.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Gets or Sets the image path.
/// </summary>
public string? ImagePath { get; set; }
/// <summary>
/// Gets or Sets the time the image was last modified.
/// </summary>
public DateTime? ImageDateModified { get; set; }
}
@@ -0,0 +1,80 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity that represents a user's custom display preferences for a specific item.
/// </summary>
public class CustomItemDisplayPreferences
{
/// <summary>
/// Initializes a new instance of the <see cref="CustomItemDisplayPreferences"/> class.
/// </summary>
/// <param name="userId">The user id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="client">The client.</param>
/// <param name="key">The preference key.</param>
/// <param name="value">The preference value.</param>
public CustomItemDisplayPreferences(Guid userId, Guid itemId, string client, string key, string? value)
{
UserId = userId;
ItemId = itemId;
Client = client;
Key = key;
Value = value;
}
/// <summary>
/// Gets the Id.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the user Id.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id of the associated item.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid ItemId { get; set; }
/// <summary>
/// Gets or sets the client string.
/// </summary>
/// <remarks>
/// Required. Max Length = 32.
/// </remarks>
[MaxLength(32)]
[StringLength(32)]
public string Client { get; set; }
/// <summary>
/// Gets or sets the preference key.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public string Key { get; set; }
/// <summary>
/// Gets or sets the preference value.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public string? Value { get; set; }
}
}
@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing a user's display preferences.
/// </summary>
public class DisplayPreferences
{
/// <summary>
/// Initializes a new instance of the <see cref="DisplayPreferences"/> class.
/// </summary>
/// <param name="userId">The user's id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="client">The client string.</param>
public DisplayPreferences(Guid userId, Guid itemId, string client)
{
UserId = userId;
ItemId = itemId;
Client = client;
ShowSidebar = false;
ShowBackdrop = true;
SkipForwardLength = 30000;
SkipBackwardLength = 10000;
ScrollDirection = ScrollDirection.Horizontal;
ChromecastVersion = ChromecastVersion.Stable;
HomeSections = new HashSet<HomeSection>();
}
/// <summary>
/// Gets the Id.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the user Id.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id of the associated item.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid ItemId { get; set; }
/// <summary>
/// Gets or sets the client string.
/// </summary>
/// <remarks>
/// Required. Max Length = 32.
/// </remarks>
[MaxLength(32)]
[StringLength(32)]
public string Client { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to show the sidebar.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool ShowSidebar { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to show the backdrop.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool ShowBackdrop { get; set; }
/// <summary>
/// Gets or sets the scroll direction.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public ScrollDirection ScrollDirection { get; set; }
/// <summary>
/// Gets or sets what the view should be indexed by.
/// </summary>
public IndexingKind? IndexBy { get; set; }
/// <summary>
/// Gets or sets the length of time to skip forwards, in milliseconds.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int SkipForwardLength { get; set; }
/// <summary>
/// Gets or sets the length of time to skip backwards, in milliseconds.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int SkipBackwardLength { get; set; }
/// <summary>
/// Gets or sets the Chromecast Version.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public ChromecastVersion ChromecastVersion { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the next video info overlay should be shown.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool EnableNextVideoInfoOverlay { get; set; }
/// <summary>
/// Gets or sets the dashboard theme.
/// </summary>
[MaxLength(32)]
[StringLength(32)]
public string? DashboardTheme { get; set; }
/// <summary>
/// Gets or sets the tv home screen.
/// </summary>
[MaxLength(32)]
[StringLength(32)]
public string? TvHome { get; set; }
/// <summary>
/// Gets the home sections.
/// </summary>
public virtual ICollection<HomeSection> HomeSections { get; private set; }
}
}
@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing a group.
/// </summary>
public class Group : IHasPermissions, IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="Group"/> class.
/// </summary>
/// <param name="name">The name of the group.</param>
public Group(string name)
{
ArgumentException.ThrowIfNullOrEmpty(name);
Name = name;
Id = Guid.NewGuid();
Permissions = new HashSet<Permission>();
Preferences = new HashSet<Preference>();
}
/// <summary>
/// Gets the id of this group.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
public Guid Id { get; private set; }
/// <summary>
/// Gets or sets the group's name.
/// </summary>
/// <remarks>
/// Required, Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string Name { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets a collection containing the group's permissions.
/// </summary>
public virtual ICollection<Permission> Permissions { get; private set; }
/// <summary>
/// Gets a collection containing the group's preferences.
/// </summary>
public virtual ICollection<Preference> Preferences { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,44 @@
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing a section on the user's home page.
/// </summary>
public class HomeSection
{
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity. Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the Id of the associated display preferences.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int DisplayPreferencesId { get; set; }
/// <summary>
/// Gets or sets the order.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int Order { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public HomeSectionType Type { get; set; }
}
}
@@ -0,0 +1,54 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing an image.
/// </summary>
public class ImageInfo
{
/// <summary>
/// Initializes a new instance of the <see cref="ImageInfo"/> class.
/// </summary>
/// <param name="path">The path.</param>
public ImageInfo(string path)
{
Path = path;
LastModified = DateTime.UtcNow;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets the user id.
/// </summary>
public Guid? UserId { get; private set; }
/// <summary>
/// Gets or sets the path of the image.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
[MaxLength(512)]
[StringLength(512)]
public string Path { get; set; }
/// <summary>
/// Gets or sets the date last modified.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public DateTime LastModified { get; set; }
}
}
@@ -0,0 +1,76 @@
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Enum ImageType.
/// </summary>
public enum ImageInfoImageType
{
/// <summary>
/// The primary.
/// </summary>
Primary = 0,
/// <summary>
/// The art.
/// </summary>
Art = 1,
/// <summary>
/// The backdrop.
/// </summary>
Backdrop = 2,
/// <summary>
/// The banner.
/// </summary>
Banner = 3,
/// <summary>
/// The logo.
/// </summary>
Logo = 4,
/// <summary>
/// The thumb.
/// </summary>
Thumb = 5,
/// <summary>
/// The disc.
/// </summary>
Disc = 6,
/// <summary>
/// The box.
/// </summary>
Box = 7,
/// <summary>
/// The screenshot.
/// </summary>
/// <remarks>
/// This enum value is obsolete.
/// XmlSerializer does not serialize/deserialize objects that are marked as [Obsolete].
/// </remarks>
Screenshot = 8,
/// <summary>
/// The menu.
/// </summary>
Menu = 9,
/// <summary>
/// The chapter image.
/// </summary>
Chapter = 10,
/// <summary>
/// The box rear.
/// </summary>
BoxRear = 11,
/// <summary>
/// The user profile image.
/// </summary>
Profile = 12
}
@@ -0,0 +1,113 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity that represents a user's display preferences for a specific item.
/// </summary>
public class ItemDisplayPreferences
{
/// <summary>
/// Initializes a new instance of the <see cref="ItemDisplayPreferences"/> class.
/// </summary>
/// <param name="userId">The user id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="client">The client.</param>
public ItemDisplayPreferences(Guid userId, Guid itemId, string client)
{
UserId = userId;
ItemId = itemId;
Client = client;
SortBy = "SortName";
SortOrder = SortOrder.Ascending;
RememberSorting = false;
RememberIndexing = false;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the user Id.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the id of the associated item.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid ItemId { get; set; }
/// <summary>
/// Gets or sets the client string.
/// </summary>
/// <remarks>
/// Required. Max Length = 32.
/// </remarks>
[MaxLength(32)]
[StringLength(32)]
public string Client { get; set; }
/// <summary>
/// Gets or sets the view type.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public ViewType ViewType { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the indexing should be remembered.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool RememberIndexing { get; set; }
/// <summary>
/// Gets or sets what the view should be indexed by.
/// </summary>
public IndexingKind? IndexBy { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the sorting type should be remembered.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool RememberSorting { get; set; }
/// <summary>
/// Gets or sets what the view should be sorted by.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
[MaxLength(64)]
[StringLength(64)]
public string SortBy { get; set; }
/// <summary>
/// Gets or sets the sort order.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public SortOrder SortOrder { get; set; }
}
}
@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Represents an ItemValue for a BaseItem.
/// </summary>
public class ItemValue
{
/// <summary>
/// Gets or Sets the ItemValueId.
/// </summary>
public required Guid ItemValueId { get; set; }
/// <summary>
/// Gets or Sets the Type.
/// </summary>
public required ItemValueType Type { get; set; }
/// <summary>
/// Gets or Sets the Value.
/// </summary>
public required string Value { get; set; }
/// <summary>
/// Gets or Sets the sanitized Value.
/// </summary>
public required string CleanValue { get; set; }
/// <summary>
/// Gets or Sets all associated BaseItems.
/// </summary>
#pragma warning disable CA2227 // Collection properties should be read only
public ICollection<ItemValueMap>? BaseItemsMap { get; set; }
#pragma warning restore CA2227 // Collection properties should be read only
}
@@ -0,0 +1,29 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Mapping table for the ItemValue BaseItem relation.
/// </summary>
public class ItemValueMap
{
/// <summary>
/// Gets or Sets the ItemId.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets the ItemValueId.
/// </summary>
public required Guid ItemValueId { get; set; }
/// <summary>
/// Gets or Sets the referenced <see cref="BaseItemEntity"/>.
/// </summary>
public required BaseItemEntity Item { get; set; }
/// <summary>
/// Gets or Sets the referenced <see cref="ItemValue"/>.
/// </summary>
public required ItemValue ItemValue { get; set; }
}
@@ -0,0 +1,38 @@
#pragma warning disable CA1027 // Mark enums with FlagsAttribute
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Provides the Value types for an <see cref="ItemValue"/>.
/// </summary>
public enum ItemValueType
{
/// <summary>
/// Artists.
/// </summary>
Artist = 0,
/// <summary>
/// Album.
/// </summary>
AlbumArtist = 1,
/// <summary>
/// Genre.
/// </summary>
Genre = 2,
/// <summary>
/// Studios.
/// </summary>
Studios = 3,
/// <summary>
/// Tags.
/// </summary>
Tags = 4,
/// <summary>
/// InheritedTags.
/// </summary>
InheritedTags = 6,
}
@@ -0,0 +1,32 @@
#pragma warning disable CA2227 // Collection properties should be read only
using System;
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Keyframe information for a specific file.
/// </summary>
public class KeyframeData
{
/// <summary>
/// Gets or Sets the ItemId.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or sets the total duration of the stream in ticks.
/// </summary>
public long TotalDuration { get; set; }
/// <summary>
/// Gets or sets the keyframes in ticks.
/// </summary>
public ICollection<long>? KeyframeTicks { get; set; }
/// <summary>
/// Gets or sets the item reference.
/// </summary>
public BaseItemEntity? Item { get; set; }
}
@@ -0,0 +1,64 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public Artwork(string path, ArtKind kind)
{
ArgumentException.ThrowIfNullOrEmpty(path);
Path = path;
Kind = kind;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <remarks>
/// Required, Max length = 65535.
/// </remarks>
[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; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
/// <param name="library">The library.</param>
public Book(Library library) : base(library)
{
BookMetadata = new HashSet<BookMetadata>();
Releases = new HashSet<Release>();
}
/// <summary>
/// Gets a collection containing the metadata for this book.
/// </summary>
public virtual ICollection<BookMetadata> BookMetadata { get; private set; }
/// <inheritdoc />
public virtual ICollection<Release> Releases { get; private set; }
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity containing metadata for a book.
/// </summary>
public class BookMetadata : ItemMetadata, 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>
public BookMetadata(string title, string language) : base(title, language)
{
Publishers = new HashSet<Company>();
}
/// <summary>
/// Gets or sets the ISBN.
/// </summary>
public long? Isbn { get; set; }
/// <summary>
/// Gets a collection of the publishers for this book.
/// </summary>
public virtual ICollection<Company> Publishers { get; private set; }
/// <inheritdoc />
public ICollection<Company> Companies => Publishers;
}
}
@@ -0,0 +1,80 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public Chapter(string language, long startTime)
{
ArgumentException.ThrowIfNullOrEmpty(language);
Language = language;
StartTime = startTime;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private 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>
[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; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,57 @@
#pragma warning disable CA1711 // Identifiers should not have incorrect suffix
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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 the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private 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; private set; }
/// <summary>
/// Gets a collection containing this collection's items.
/// </summary>
public virtual ICollection<CollectionItem> Items { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,64 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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="libraryItem">The library item.</param>
public CollectionItem(LibraryItem libraryItem)
{
LibraryItem = libraryItem;
}
/// <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; private 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 Dependent 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 Dependent and has the proper principal relationship.
/// </remarks>
public virtual CollectionItem? Previous { get; set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,54 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public Company()
{
CompanyMetadata = new HashSet<CompanyMetadata>();
ChildCompanies = new HashSet<Company>();
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets a collection containing the metadata.
/// </summary>
public virtual ICollection<CompanyMetadata> CompanyMetadata { get; private set; }
/// <summary>
/// Gets a collection containing this company's child companies.
/// </summary>
public virtual ICollection<Company> ChildCompanies { get; private set; }
/// <inheritdoc />
public ICollection<Company> Companies => ChildCompanies;
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,59 @@
using System.ComponentModel.DataAnnotations;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity holding metadata for a <see cref="Company"/>.
/// </summary>
public class CompanyMetadata : ItemMetadata
{
/// <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>
public CompanyMetadata(string title, string language) : base(title, language)
{
}
/// <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; }
}
}
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
/// <param name="library">The library.</param>
public CustomItem(Library library) : base(library)
{
CustomItemMetadata = new HashSet<CustomItemMetadata>();
Releases = new HashSet<Release>();
}
/// <summary>
/// Gets a collection containing the metadata for this item.
/// </summary>
public virtual ICollection<CustomItemMetadata> CustomItemMetadata { get; private set; }
/// <inheritdoc />
public virtual ICollection<Release> Releases { get; private set; }
}
}
@@ -0,0 +1,17 @@
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity containing metadata for a custom item.
/// </summary>
public class CustomItemMetadata : ItemMetadata
{
/// <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>
public CustomItemMetadata(string title, string language) : base(title, language)
{
}
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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="library">The library.</param>
public Episode(Library library) : base(library)
{
Releases = new HashSet<Release>();
EpisodeMetadata = new HashSet<EpisodeMetadata>();
}
/// <summary>
/// Gets or sets the episode number.
/// </summary>
public int? EpisodeNumber { get; set; }
/// <inheritdoc />
public virtual ICollection<Release> Releases { get; private set; }
/// <summary>
/// Gets a collection containing the metadata for this episode.
/// </summary>
public virtual ICollection<EpisodeMetadata> EpisodeMetadata { get; private set; }
}
}
@@ -0,0 +1,49 @@
using System.ComponentModel.DataAnnotations;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity containing metadata for an <see cref="Episode"/>.
/// </summary>
public class EpisodeMetadata : ItemMetadata
{
/// <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>
public EpisodeMetadata(string title, string language) : base(title, language)
{
}
/// <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; }
}
}
@@ -0,0 +1,50 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public Genre(string name)
{
Name = name;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <remarks>
/// Indexed, Required, Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string Name { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,141 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An abstract class that holds metadata.
/// </summary>
public abstract class ItemMetadata : IHasArtwork, IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="ItemMetadata"/> 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 ItemMetadata(string title, string language)
{
ArgumentException.ThrowIfNullOrEmpty(title);
ArgumentException.ThrowIfNullOrEmpty(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>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the title.
/// </summary>
/// <remarks>
/// Required, Max length = 1024.
/// </remarks>
[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>
[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 the date added.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public DateTime DateAdded { get; private set; }
/// <summary>
/// Gets or sets the date modified.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public DateTime DateModified { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets a collection containing the person roles for this item.
/// </summary>
public virtual ICollection<PersonRole> PersonRoles { get; private set; }
/// <summary>
/// Gets a collection containing the genres for this item.
/// </summary>
public virtual ICollection<Genre> Genres { get; private set; }
/// <inheritdoc />
public virtual ICollection<Artwork> Artwork { get; private set; }
/// <summary>
/// Gets a collection containing the ratings for this item.
/// </summary>
public virtual ICollection<Rating> Ratings { get; private set; }
/// <summary>
/// Gets a collection containing the metadata sources for this item.
/// </summary>
public virtual ICollection<MetadataProviderId> Sources { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,60 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
/// <param name="path">The path of the library.</param>
public Library(string name, string path)
{
Name = name;
Path = path;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <remarks>
/// Required, Max length = 128.
/// </remarks>
[MaxLength(128)]
[StringLength(128)]
public string Name { get; set; }
/// <summary>
/// Gets or sets the root path of the library.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public string Path { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,55 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets the date this library item was added.
/// </summary>
public DateTime DateAdded { get; private set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets or sets the library of this item.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public virtual Library Library { get; set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public MediaFile(string path, MediaFileKind kind)
{
ArgumentException.ThrowIfNullOrEmpty(path);
Path = path;
Kind = kind;
MediaFileStreams = new HashSet<MediaFileStream>();
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the path relative to the library root.
/// </summary>
/// <remarks>
/// Required, Max length = 65535.
/// </remarks>
[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; private set; }
/// <summary>
/// Gets a collection containing the streams in this file.
/// </summary>
public virtual ICollection<MediaFileStream> MediaFileStreams { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,50 @@
#pragma warning disable CA1711 // Identifiers should not have incorrect suffix
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public MediaFileStream(int streamNumber)
{
StreamNumber = streamNumber;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the stream number.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int StreamNumber { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,53 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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)
{
ArgumentException.ThrowIfNullOrEmpty(name);
Name = name;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <remarks>
/// Required, Max length = 1024.
/// </remarks>
[MaxLength(1024)]
[StringLength(1024)]
public string Name { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,63 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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="metadataProvider">The metadata provider.</param>
public MetadataProviderId(string providerId, MetadataProvider metadataProvider)
{
ArgumentException.ThrowIfNullOrEmpty(providerId);
ProviderId = providerId;
MetadataProvider = metadataProvider;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the provider id.
/// </summary>
/// <remarks>
/// Required, Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string ProviderId { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets or sets the metadata provider.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public virtual MetadataProvider MetadataProvider { get; set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
/// <param name="library">The library.</param>
public Movie(Library library) : base(library)
{
Releases = new HashSet<Release>();
MovieMetadata = new HashSet<MovieMetadata>();
}
/// <inheritdoc />
public virtual ICollection<Release> Releases { get; private set; }
/// <summary>
/// Gets a collection containing the metadata for this movie.
/// </summary>
public virtual ICollection<MovieMetadata> MovieMetadata { get; private set; }
}
}
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity holding the metadata for a movie.
/// </summary>
public class MovieMetadata : ItemMetadata, 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>
public MovieMetadata(string title, string language) : base(title, language)
{
Studios = new HashSet<Company>();
}
/// <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 the studios that produced this movie.
/// </summary>
public virtual ICollection<Company> Studios { get; private set; }
/// <inheritdoc />
public ICollection<Company> Companies => Studios;
}
}
@@ -0,0 +1,30 @@
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.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>
/// <param name="library">The library.</param>
public MusicAlbum(Library library) : base(library)
{
MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>();
Tracks = new HashSet<Track>();
}
/// <summary>
/// Gets a collection containing the album metadata.
/// </summary>
public virtual ICollection<MusicAlbumMetadata> MusicAlbumMetadata { get; private set; }
/// <summary>
/// Gets a collection containing the tracks.
/// </summary>
public virtual ICollection<Track> Tracks { get; private set; }
}
}
@@ -0,0 +1,56 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity holding the metadata for a music album.
/// </summary>
public class MusicAlbumMetadata : ItemMetadata
{
/// <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>
public MusicAlbumMetadata(string title, string language) : base(title, language)
{
Labels = new HashSet<Company>();
}
/// <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 a collection containing the labels.
/// </summary>
public virtual ICollection<Company> Labels { get; private set; }
}
}
@@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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)
{
ArgumentException.ThrowIfNullOrEmpty(name);
Name = name;
DateAdded = DateTime.UtcNow;
DateModified = DateAdded;
Sources = new HashSet<MetadataProviderId>();
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <remarks>
/// Required, Max length = 1024.
/// </remarks>
[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 the date added.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public DateTime DateAdded { get; private set; }
/// <summary>
/// Gets or sets the date modified.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public DateTime DateModified { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets a list of metadata sources for this person.
/// </summary>
public virtual ICollection<MetadataProviderId> Sources { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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="person">The person.</param>
public PersonRole(PersonRoleType type, Person person)
{
Type = type;
Person = person;
Artwork = new HashSet<Artwork>();
Sources = new HashSet<MetadataProviderId>();
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private 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; private set; }
/// <summary>
/// Gets or sets the person.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public virtual Person Person { get; set; }
/// <inheritdoc />
public virtual ICollection<Artwork> Artwork { get; private set; }
/// <summary>
/// Gets a collection containing the metadata sources for this person role.
/// </summary>
public virtual ICollection<MetadataProviderId> Sources { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
/// <param name="library">The library.</param>
public Photo(Library library) : base(library)
{
PhotoMetadata = new HashSet<PhotoMetadata>();
Releases = new HashSet<Release>();
}
/// <summary>
/// Gets a collection containing the photo metadata.
/// </summary>
public virtual ICollection<PhotoMetadata> PhotoMetadata { get; private set; }
/// <inheritdoc />
public virtual ICollection<Release> Releases { get; private set; }
}
}
@@ -0,0 +1,17 @@
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity that holds metadata for a photo.
/// </summary>
public class PhotoMetadata : ItemMetadata
{
/// <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>
public PhotoMetadata(string title, string language) : base(title, language)
{
}
}
}
@@ -0,0 +1,59 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public Rating(double value)
{
Value = value;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private 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; private 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++;
}
}
}
@@ -0,0 +1,73 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public RatingSource(double minimumValue, double maximumValue)
{
MinimumValue = minimumValue;
MaximumValue = maximumValue;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private 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; private set; }
/// <summary>
/// Gets or sets the metadata source.
/// </summary>
public virtual MetadataProviderId? Source { get; set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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>
public Release(string name)
{
ArgumentException.ThrowIfNullOrEmpty(name);
Name = name;
MediaFiles = new HashSet<MediaFile>();
Chapters = new HashSet<Chapter>();
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <remarks>
/// Required, Max length = 1024.
/// </remarks>
[MaxLength(1024)]
[StringLength(1024)]
public string Name { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets a collection containing the media files for this release.
/// </summary>
public virtual ICollection<MediaFile> MediaFiles { get; private set; }
/// <summary>
/// Gets a collection containing the chapters for this release.
/// </summary>
public virtual ICollection<Chapter> Chapters { get; private set; }
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,35 @@
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.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="library">The library.</param>
public Season(Library library) : base(library)
{
Episodes = new HashSet<Episode>();
SeasonMetadata = new HashSet<SeasonMetadata>();
}
/// <summary>
/// Gets or sets the season number.
/// </summary>
public int? SeasonNumber { get; set; }
/// <summary>
/// Gets the season metadata.
/// </summary>
public virtual ICollection<SeasonMetadata> SeasonMetadata { get; private set; }
/// <summary>
/// Gets a collection containing the number of episodes.
/// </summary>
public virtual ICollection<Episode> Episodes { get; private set; }
}
}
@@ -0,0 +1,29 @@
using System.ComponentModel.DataAnnotations;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity that holds metadata for seasons.
/// </summary>
public class SeasonMetadata : ItemMetadata
{
/// <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>
public SeasonMetadata(string title, string language) : base(title, language)
{
}
/// <summary>
/// Gets or sets the outline.
/// </summary>
/// <remarks>
/// Max length = 1024.
/// </remarks>
[MaxLength(1024)]
[StringLength(1024)]
public string? Outline { get; set; }
}
}
@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity representing a series.
/// </summary>
public class Series : LibraryItem
{
/// <summary>
/// Initializes a new instance of the <see cref="Series"/> class.
/// </summary>
/// <param name="library">The library.</param>
public Series(Library library) : base(library)
{
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 a collection containing the series metadata.
/// </summary>
public virtual ICollection<SeriesMetadata> SeriesMetadata { get; private set; }
/// <summary>
/// Gets a collection containing the seasons.
/// </summary>
public virtual ICollection<Season> Seasons { get; private set; }
}
}
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity representing series metadata.
/// </summary>
public class SeriesMetadata : ItemMetadata, 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>
public SeriesMetadata(string title, string language) : base(title, language)
{
Networks = new HashSet<Company>();
}
/// <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 a collection containing the networks.
/// </summary>
public virtual ICollection<Company> Networks { get; private set; }
/// <inheritdoc />
public ICollection<Company> Companies => Networks;
}
}
@@ -0,0 +1,34 @@
using System.Collections.Generic;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.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="library">The library.</param>
public Track(Library library) : base(library)
{
Releases = new HashSet<Release>();
TrackMetadata = new HashSet<TrackMetadata>();
}
/// <summary>
/// Gets or sets the track number.
/// </summary>
public int? TrackNumber { get; set; }
/// <inheritdoc />
public virtual ICollection<Release> Releases { get; private set; }
/// <summary>
/// Gets a collection containing the track metadata.
/// </summary>
public virtual ICollection<TrackMetadata> TrackMetadata { get; private set; }
}
}
@@ -0,0 +1,17 @@
namespace Jellyfin.Database.Implementations.Entities.Libraries
{
/// <summary>
/// An entity holding metadata for a track.
/// </summary>
public class TrackMetadata : ItemMetadata
{
/// <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>
public TrackMetadata(string title, string language) : base(title, language)
{
}
}
}
@@ -0,0 +1,42 @@
using System;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// An entity representing the metadata for a group of trickplay tiles.
/// </summary>
public class MediaSegment
{
/// <summary>
/// Gets or sets the id of the media segment.
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
/// <summary>
/// Gets or sets the id of the associated item.
/// </summary>
public Guid ItemId { get; set; }
/// <summary>
/// Gets or sets the Type of content this segment defines.
/// </summary>
public MediaSegmentType Type { get; set; }
/// <summary>
/// Gets or sets the end of the segment.
/// </summary>
public long EndTicks { get; set; }
/// <summary>
/// Gets or sets the start of the segment.
/// </summary>
public long StartTicks { get; set; }
/// <summary>
/// Gets or sets Id of the media segment provider this entry originates from.
/// </summary>
public required string SegmentProviderId { get; set; }
}
@@ -0,0 +1,104 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System;
namespace Jellyfin.Database.Implementations.Entities;
public class MediaStreamInfo
{
public required Guid ItemId { get; set; }
public required BaseItemEntity Item { get; set; }
public int StreamIndex { get; set; }
public required MediaStreamTypeEntity StreamType { get; set; }
public string? Codec { get; set; }
public string? Language { get; set; }
public string? ChannelLayout { get; set; }
public string? Profile { get; set; }
public string? AspectRatio { get; set; }
public string? Path { get; set; }
public bool? IsInterlaced { get; set; }
public int? BitRate { get; set; }
public int? Channels { get; set; }
public int? SampleRate { get; set; }
public bool IsDefault { get; set; }
public bool IsForced { get; set; }
public bool IsExternal { get; set; }
public int? Height { get; set; }
public int? Width { get; set; }
public float? AverageFrameRate { get; set; }
public float? RealFrameRate { get; set; }
public float? Level { get; set; }
public string? PixelFormat { get; set; }
public int? BitDepth { get; set; }
public bool? IsAnamorphic { get; set; }
public int? RefFrames { get; set; }
public string? CodecTag { get; set; }
public string? Comment { get; set; }
public string? NalLengthSize { get; set; }
public bool? IsAvc { get; set; }
public string? Title { get; set; }
public string? TimeBase { get; set; }
public string? CodecTimeBase { get; set; }
public string? ColorPrimaries { get; set; }
public string? ColorSpace { get; set; }
public string? ColorTransfer { get; set; }
public int? DvVersionMajor { get; set; }
public int? DvVersionMinor { get; set; }
public int? DvProfile { get; set; }
public int? DvLevel { get; set; }
public int? RpuPresentFlag { get; set; }
public int? ElPresentFlag { get; set; }
public int? BlPresentFlag { get; set; }
public int? DvBlSignalCompatibilityId { get; set; }
public bool? IsHearingImpaired { get; set; }
public int? Rotation { get; set; }
public string? KeyFrames { get; set; }
public bool? Hdr10PlusPresentFlag { get; set; }
}
@@ -0,0 +1,37 @@
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Enum MediaStreamType.
/// </summary>
public enum MediaStreamTypeEntity
{
/// <summary>
/// The audio.
/// </summary>
Audio = 0,
/// <summary>
/// The video.
/// </summary>
Video = 1,
/// <summary>
/// The subtitle.
/// </summary>
Subtitle = 2,
/// <summary>
/// The embedded image.
/// </summary>
EmbeddedImage = 3,
/// <summary>
/// The data.
/// </summary>
Data = 4,
/// <summary>
/// The lyric.
/// </summary>
Lyric = 5
}
@@ -0,0 +1,32 @@
#pragma warning disable CA2227 // Collection properties should be read only
using System;
using System.Collections.Generic;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// People entity.
/// </summary>
public class People
{
/// <summary>
/// Gets or Sets the PeopleId.
/// </summary>
public required Guid Id { get; set; }
/// <summary>
/// Gets or Sets the Persons Name.
/// </summary>
public required string Name { get; set; }
/// <summary>
/// Gets or Sets the Type.
/// </summary>
public string? PersonType { get; set; }
/// <summary>
/// Gets or Sets the mapping of People to BaseItems.
/// </summary>
public ICollection<PeopleBaseItemMap>? BaseItems { get; set; }
}
@@ -0,0 +1,44 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Mapping table for People to BaseItems.
/// </summary>
public class PeopleBaseItemMap
{
/// <summary>
/// Gets or Sets the SortOrder.
/// </summary>
public int? SortOrder { get; set; }
/// <summary>
/// Gets or Sets the ListOrder.
/// </summary>
public int? ListOrder { get; set; }
/// <summary>
/// Gets or Sets the Role name the associated actor played in the <see cref="BaseItemEntity"/>.
/// </summary>
public string? Role { get; set; }
/// <summary>
/// Gets or Sets The ItemId.
/// </summary>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets Reference Item.
/// </summary>
public required BaseItemEntity Item { get; set; }
/// <summary>
/// Gets or Sets The PeopleId.
/// </summary>
public required Guid PeopleId { get; set; }
/// <summary>
/// Gets or Sets Reference People.
/// </summary>
public required People People { get; set; }
}
@@ -0,0 +1,68 @@
#pragma warning disable CA1711 // Identifiers should not have incorrect suffix
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing whether the associated user has a specific permission.
/// </summary>
public class Permission : IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="Permission"/> class.
/// Public constructor with required data.
/// </summary>
/// <param name="kind">The permission kind.</param>
/// <param name="value">The value of this permission.</param>
public Permission(PermissionKind kind, bool value)
{
Kind = kind;
Value = value;
}
/// <summary>
/// Gets the id of this permission.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the id of the associated user.
/// </summary>
public Guid? UserId { get; set; }
/// <summary>
/// Gets the type of this permission.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public PermissionKind Kind { get; private set; }
/// <summary>
/// Gets or sets a value indicating whether the associated user has this permission.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool Value { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <inheritdoc/>
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,68 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing a preference attached to a user or group.
/// </summary>
public class Preference : IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="Preference"/> class.
/// Public constructor with required data.
/// </summary>
/// <param name="kind">The preference kind.</param>
/// <param name="value">The value.</param>
public Preference(PreferenceKind kind, string value)
{
Kind = kind;
Value = value ?? throw new ArgumentNullException(nameof(value));
}
/// <summary>
/// Gets the id of this preference.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the id of the associated user.
/// </summary>
public Guid? UserId { get; set; }
/// <summary>
/// Gets the type of this preference.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public PreferenceKind Kind { get; private set; }
/// <summary>
/// Gets or sets the value of this preference.
/// </summary>
/// <remarks>
/// Required, Max length = 65535.
/// </remarks>
[MaxLength(65535)]
[StringLength(65535)]
public string Value { get; set; }
/// <inheritdoc/>
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <inheritdoc/>
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,37 @@
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Lists types of Audio.
/// </summary>
public enum ProgramAudioEntity
{
/// <summary>
/// Mono.
/// </summary>
Mono = 0,
/// <summary>
/// Stereo.
/// </summary>
Stereo = 1,
/// <summary>
/// Dolby.
/// </summary>
Dolby = 2,
/// <summary>
/// DolbyDigital.
/// </summary>
DolbyDigital = 3,
/// <summary>
/// Thx.
/// </summary>
Thx = 4,
/// <summary>
/// Atmos.
/// </summary>
Atmos = 5
}
@@ -0,0 +1,56 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Globalization;
namespace Jellyfin.Database.Implementations.Entities.Security
{
/// <summary>
/// An entity representing an API key.
/// </summary>
public class ApiKey
{
/// <summary>
/// Initializes a new instance of the <see cref="ApiKey"/> class.
/// </summary>
/// <param name="name">The name.</param>
public ApiKey(string name)
{
Name = name;
AccessToken = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
DateCreated = DateTime.UtcNow;
}
/// <summary>
/// Gets the id.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets or sets the date created.
/// </summary>
public DateTime DateCreated { get; set; }
/// <summary>
/// Gets or sets the date of last activity.
/// </summary>
public DateTime DateLastActivity { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
[MaxLength(64)]
[StringLength(64)]
public string Name { get; set; }
/// <summary>
/// Gets or sets the access token.
/// </summary>
public string AccessToken { get; set; }
}
}
@@ -0,0 +1,107 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Globalization;
namespace Jellyfin.Database.Implementations.Entities.Security
{
/// <summary>
/// An entity representing a device.
/// </summary>
public class Device
{
/// <summary>
/// Initializes a new instance of the <see cref="Device"/> class.
/// </summary>
/// <param name="userId">The user id.</param>
/// <param name="appName">The app name.</param>
/// <param name="appVersion">The app version.</param>
/// <param name="deviceName">The device name.</param>
/// <param name="deviceId">The device id.</param>
public Device(Guid userId, string appName, string appVersion, string deviceName, string deviceId)
{
UserId = userId;
AppName = appName;
AppVersion = appVersion;
DeviceName = deviceName;
DeviceId = deviceId;
AccessToken = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
DateCreated = DateTime.UtcNow;
DateModified = DateCreated;
DateLastActivity = DateCreated;
// Non-nullable for EF Core, as this is a required relationship.
User = null!;
}
/// <summary>
/// Gets the id.
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets the user id.
/// </summary>
public Guid UserId { get; private set; }
/// <summary>
/// Gets or sets the access token.
/// </summary>
public string AccessToken { get; set; }
/// <summary>
/// Gets or sets the app name.
/// </summary>
[MaxLength(64)]
[StringLength(64)]
public string AppName { get; set; }
/// <summary>
/// Gets or sets the app version.
/// </summary>
[MaxLength(32)]
[StringLength(32)]
public string AppVersion { get; set; }
/// <summary>
/// Gets or sets the device name.
/// </summary>
[MaxLength(64)]
[StringLength(64)]
public string DeviceName { get; set; }
/// <summary>
/// Gets or sets the device id.
/// </summary>
[MaxLength(256)]
[StringLength(256)]
public string DeviceId { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this device is active.
/// </summary>
public bool IsActive { get; set; }
/// <summary>
/// Gets or sets the date created.
/// </summary>
public DateTime DateCreated { get; set; }
/// <summary>
/// Gets or sets the date modified.
/// </summary>
public DateTime DateModified { get; set; }
/// <summary>
/// Gets or sets the date of last activity.
/// </summary>
public DateTime DateLastActivity { get; set; }
/// <summary>
/// Gets the user.
/// </summary>
public User User { get; private set; }
}
}
@@ -0,0 +1,35 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace Jellyfin.Database.Implementations.Entities.Security
{
/// <summary>
/// An entity representing custom options for a device.
/// </summary>
public class DeviceOptions
{
/// <summary>
/// Initializes a new instance of the <see cref="DeviceOptions"/> class.
/// </summary>
/// <param name="deviceId">The device id.</param>
public DeviceOptions(string deviceId)
{
DeviceId = deviceId;
}
/// <summary>
/// Gets the id.
/// </summary>
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; private set; }
/// <summary>
/// Gets the device id.
/// </summary>
public string DeviceId { get; private set; }
/// <summary>
/// Gets or sets the custom name.
/// </summary>
public string? CustomName { get; set; }
}
}
@@ -0,0 +1,74 @@
using System;
using System.Text.Json.Serialization;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// An entity representing the metadata for a group of trickplay tiles.
/// </summary>
public class TrickplayInfo
{
/// <summary>
/// Gets or sets the id of the associated item.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public Guid ItemId { get; set; }
/// <summary>
/// Gets or sets width of an individual thumbnail.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int Width { get; set; }
/// <summary>
/// Gets or sets height of an individual thumbnail.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int Height { get; set; }
/// <summary>
/// Gets or sets amount of thumbnails per row.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int TileWidth { get; set; }
/// <summary>
/// Gets or sets amount of thumbnails per column.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int TileHeight { get; set; }
/// <summary>
/// Gets or sets total amount of non-black thumbnails.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int ThumbnailCount { get; set; }
/// <summary>
/// Gets or sets interval in milliseconds between each trickplay thumbnail.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int Interval { get; set; }
/// <summary>
/// Gets or sets peak bandwidth usage in bits per second.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int Bandwidth { get; set; }
}
@@ -0,0 +1,340 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Database.Implementations.Entities
{
/// <summary>
/// An entity representing a user.
/// </summary>
public class User : IHasPermissions, IHasConcurrencyToken
{
/// <summary>
/// Initializes a new instance of the <see cref="User"/> class.
/// Public constructor with required data.
/// </summary>
/// <param name="username">The username for the new user.</param>
/// <param name="authenticationProviderId">The Id of the user's authentication provider.</param>
/// <param name="passwordResetProviderId">The Id of the user's password reset provider.</param>
public User(string username, string authenticationProviderId, string passwordResetProviderId)
{
ArgumentException.ThrowIfNullOrEmpty(username);
ArgumentException.ThrowIfNullOrEmpty(authenticationProviderId);
ArgumentException.ThrowIfNullOrEmpty(passwordResetProviderId);
Username = username;
AuthenticationProviderId = authenticationProviderId;
PasswordResetProviderId = passwordResetProviderId;
AccessSchedules = new HashSet<AccessSchedule>();
DisplayPreferences = new HashSet<DisplayPreferences>();
ItemDisplayPreferences = new HashSet<ItemDisplayPreferences>();
// Groups = new HashSet<Group>();
Permissions = new HashSet<Permission>();
Preferences = new HashSet<Preference>();
// ProviderMappings = new HashSet<ProviderMapping>();
// Set default values
Id = Guid.NewGuid();
InvalidLoginAttemptCount = 0;
EnableUserPreferenceAccess = true;
MustUpdatePassword = false;
DisplayMissingEpisodes = false;
DisplayCollectionsView = false;
HidePlayedInLatest = true;
RememberAudioSelections = true;
RememberSubtitleSelections = true;
EnableNextEpisodeAutoPlay = true;
EnableAutoLogin = false;
PlayDefaultAudioTrack = true;
SubtitleMode = SubtitlePlaybackMode.Default;
SyncPlayAccess = SyncPlayUserAccessType.CreateAndJoinGroups;
}
/// <summary>
/// Gets or sets the Id of the user.
/// </summary>
/// <remarks>
/// Identity, Indexed, Required.
/// </remarks>
public Guid Id { get; set; }
/// <summary>
/// Gets or sets the user's name.
/// </summary>
/// <remarks>
/// Required, Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string Username { get; set; }
/// <summary>
/// Gets or sets the user's password, or <c>null</c> if none is set.
/// </summary>
/// <remarks>
/// Max length = 65535.
/// </remarks>
[MaxLength(65535)]
[StringLength(65535)]
public string? Password { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the user must update their password.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool MustUpdatePassword { get; set; }
/// <summary>
/// Gets or sets the audio language preference.
/// </summary>
/// <remarks>
/// Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string? AudioLanguagePreference { get; set; }
/// <summary>
/// Gets or sets the authentication provider id.
/// </summary>
/// <remarks>
/// Required, Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string AuthenticationProviderId { get; set; }
/// <summary>
/// Gets or sets the password reset provider id.
/// </summary>
/// <remarks>
/// Required, Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string PasswordResetProviderId { get; set; }
/// <summary>
/// Gets or sets the invalid login attempt count.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public int InvalidLoginAttemptCount { get; set; }
/// <summary>
/// Gets or sets the last activity date.
/// </summary>
public DateTime? LastActivityDate { get; set; }
/// <summary>
/// Gets or sets the last login date.
/// </summary>
public DateTime? LastLoginDate { get; set; }
/// <summary>
/// Gets or sets the number of login attempts the user can make before they are locked out.
/// </summary>
public int? LoginAttemptsBeforeLockout { get; set; }
/// <summary>
/// Gets or sets the maximum number of active sessions the user can have at once.
/// </summary>
public int MaxActiveSessions { get; set; }
/// <summary>
/// Gets or sets the subtitle mode.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public SubtitlePlaybackMode SubtitleMode { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the default audio track should be played.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool PlayDefaultAudioTrack { get; set; }
/// <summary>
/// Gets or sets the subtitle language preference.
/// </summary>
/// <remarks>
/// Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string? SubtitleLanguagePreference { get; set; }
/// <summary>
/// Gets or sets a value indicating whether missing episodes should be displayed.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool DisplayMissingEpisodes { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to display the collections view.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool DisplayCollectionsView { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the user has a local password.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool EnableLocalPassword { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the server should hide played content in "Latest".
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool HidePlayedInLatest { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to remember audio selections on played content.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool RememberAudioSelections { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to remember subtitle selections on played content.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool RememberSubtitleSelections { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to enable auto-play for the next episode.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool EnableNextEpisodeAutoPlay { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the user should auto-login.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool EnableAutoLogin { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the user can change their preferences.
/// </summary>
/// <remarks>
/// Required.
/// </remarks>
public bool EnableUserPreferenceAccess { get; set; }
/// <summary>
/// Gets or sets the maximum parental rating score.
/// </summary>
public int? MaxParentalRatingScore { get; set; }
/// <summary>
/// Gets or sets the maximum parental rating sub score.
/// </summary>
public int? MaxParentalRatingSubScore { get; set; }
/// <summary>
/// Gets or sets the remote client bitrate limit.
/// </summary>
public int? RemoteClientBitrateLimit { get; set; }
/// <summary>
/// Gets or sets the internal id.
/// This is a temporary stopgap for until the library db is migrated.
/// This corresponds to the value of the index of this user in the library db.
/// </summary>
public long InternalId { get; set; }
/// <summary>
/// Gets or sets the user's profile image. Can be <c>null</c>.
/// </summary>
// [ForeignKey("UserId")]
public virtual ImageInfo? ProfileImage { get; set; }
/// <summary>
/// Gets the user's display preferences.
/// </summary>
public virtual ICollection<DisplayPreferences> DisplayPreferences { get; private set; }
/// <summary>
/// Gets or sets the level of sync play permissions this user has.
/// </summary>
public SyncPlayUserAccessType SyncPlayAccess { get; set; }
/// <summary>
/// Gets or sets the cast receiver id.
/// </summary>
[StringLength(32)]
public string? CastReceiverId { get; set; }
/// <inheritdoc />
[ConcurrencyCheck]
public uint RowVersion { get; private set; }
/// <summary>
/// Gets the list of access schedules this user has.
/// </summary>
public virtual ICollection<AccessSchedule> AccessSchedules { get; private set; }
/// <summary>
/// Gets the list of item display preferences.
/// </summary>
public virtual ICollection<ItemDisplayPreferences> ItemDisplayPreferences { get; private set; }
/*
/// <summary>
/// Gets the list of groups this user is a member of.
/// </summary>
public virtual ICollection<Group> Groups { get; private set; }
*/
/// <summary>
/// Gets the list of permissions this user has.
/// </summary>
[ForeignKey("Permission_Permissions_Guid")]
public virtual ICollection<Permission> Permissions { get; private set; }
/*
/// <summary>
/// Gets the list of provider mappings this user has.
/// </summary>
public virtual ICollection<ProviderMapping> ProviderMappings { get; private set; }
*/
/// <summary>
/// Gets the list of preferences this user has.
/// </summary>
[ForeignKey("Preference_Preferences_Guid")]
public virtual ICollection<Preference> Preferences { get; private set; }
/// <inheritdoc/>
public void OnSavingChanges()
{
RowVersion++;
}
}
}
@@ -0,0 +1,96 @@
using System;
namespace Jellyfin.Database.Implementations.Entities;
/// <summary>
/// Provides <see cref="BaseItemEntity"/> and <see cref="User"/> related data.
/// </summary>
public class UserData
{
/// <summary>
/// Gets or sets the custom data key.
/// </summary>
/// <value>The rating.</value>
public required string CustomDataKey { get; set; }
/// <summary>
/// Gets or sets the users 0-10 rating.
/// </summary>
/// <value>The rating.</value>
public double? Rating { get; set; }
/// <summary>
/// Gets or sets the playback position ticks.
/// </summary>
/// <value>The playback position ticks.</value>
public long PlaybackPositionTicks { get; set; }
/// <summary>
/// Gets or sets the play count.
/// </summary>
/// <value>The play count.</value>
public int PlayCount { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance is favorite.
/// </summary>
/// <value><c>true</c> if this instance is favorite; otherwise, <c>false</c>.</value>
public bool IsFavorite { get; set; }
/// <summary>
/// Gets or sets the last played date.
/// </summary>
/// <value>The last played date.</value>
public DateTime? LastPlayedDate { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this <see cref="UserData" /> is played.
/// </summary>
/// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
public bool Played { get; set; }
/// <summary>
/// Gets or sets the index of the audio stream.
/// </summary>
/// <value>The index of the audio stream.</value>
public int? AudioStreamIndex { get; set; }
/// <summary>
/// Gets or sets the index of the subtitle stream.
/// </summary>
/// <value>The index of the subtitle stream.</value>
public int? SubtitleStreamIndex { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the item is liked or not.
/// This should never be serialized.
/// </summary>
/// <value><c>null</c> if [likes] contains no value, <c>true</c> if [likes]; otherwise, <c>false</c>.</value>
public bool? Likes { get; set; }
/// <summary>
/// Gets or Sets the date the referenced <see cref="Item"/> has been deleted.
/// </summary>
public DateTime? RetentionDate { get; set; }
/// <summary>
/// Gets or sets the key.
/// </summary>
/// <value>The key.</value>
public required Guid ItemId { get; set; }
/// <summary>
/// Gets or Sets the BaseItem.
/// </summary>
public required BaseItemEntity? Item { get; set; }
/// <summary>
/// Gets or Sets the UserId.
/// </summary>
public required Guid UserId { get; set; }
/// <summary>
/// Gets or Sets the User.
/// </summary>
public required User? User { get; set; }
}
@@ -0,0 +1,32 @@
namespace Jellyfin.Database.Implementations.Enums;
/// <summary>
/// An enum representing types of art.
/// </summary>
public enum ArtKind
{
/// <summary>
/// Another type of art, not covered by the other members.
/// </summary>
Other = 0,
/// <summary>
/// A poster.
/// </summary>
Poster = 1,
/// <summary>
/// A banner.
/// </summary>
Banner = 2,
/// <summary>
/// A thumbnail.
/// </summary>
Thumbnail = 3,
/// <summary>
/// A logo.
/// </summary>
Logo = 4
}
@@ -0,0 +1,17 @@
namespace Jellyfin.Database.Implementations.Enums;
/// <summary>
/// An enum representing the version of Chromecast to be used by clients.
/// </summary>
public enum ChromecastVersion
{
/// <summary>
/// Stable Chromecast version.
/// </summary>
Stable = 0,
/// <summary>
/// Unstable Chromecast version.
/// </summary>
Unstable = 1
}
@@ -0,0 +1,57 @@
namespace Jellyfin.Database.Implementations.Enums;
/// <summary>
/// An enum that represents a day of the week, weekdays, weekends, or all days.
/// </summary>
public enum DynamicDayOfWeek
{
/// <summary>
/// Sunday.
/// </summary>
Sunday = 0,
/// <summary>
/// Monday.
/// </summary>
Monday = 1,
/// <summary>
/// Tuesday.
/// </summary>
Tuesday = 2,
/// <summary>
/// Wednesday.
/// </summary>
Wednesday = 3,
/// <summary>
/// Thursday.
/// </summary>
Thursday = 4,
/// <summary>
/// Friday.
/// </summary>
Friday = 5,
/// <summary>
/// Saturday.
/// </summary>
Saturday = 6,
/// <summary>
/// All days of the week.
/// </summary>
Everyday = 7,
/// <summary>
/// A week day, or Monday-Friday.
/// </summary>
Weekday = 8,
/// <summary>
/// Saturday and Sunday.
/// </summary>
Weekend = 9
}
@@ -0,0 +1,57 @@
namespace Jellyfin.Database.Implementations.Enums;
/// <summary>
/// An enum representing the different options for the home screen sections.
/// </summary>
public enum HomeSectionType
{
/// <summary>
/// None.
/// </summary>
None = 0,
/// <summary>
/// My Media.
/// </summary>
SmallLibraryTiles = 1,
/// <summary>
/// My Media Small.
/// </summary>
LibraryButtons = 2,
/// <summary>
/// Active Recordings.
/// </summary>
ActiveRecordings = 3,
/// <summary>
/// Continue Watching.
/// </summary>
Resume = 4,
/// <summary>
/// Continue Listening.
/// </summary>
ResumeAudio = 5,
/// <summary>
/// Latest Media.
/// </summary>
LatestMedia = 6,
/// <summary>
/// Next Up.
/// </summary>
NextUp = 7,
/// <summary>
/// Live TV.
/// </summary>
LiveTv = 8,
/// <summary>
/// Continue Reading.
/// </summary>
ResumeBook = 9
}
@@ -0,0 +1,22 @@
namespace Jellyfin.Database.Implementations.Enums;
/// <summary>
/// An enum representing a type of indexing in a user's display preferences.
/// </summary>
public enum IndexingKind
{
/// <summary>
/// Index by the premiere date.
/// </summary>
PremiereDate = 0,
/// <summary>
/// Index by the production year.
/// </summary>
ProductionYear = 1,
/// <summary>
/// Index by the community rating.
/// </summary>
CommunityRating = 2
}

Some files were not shown because too many files have changed in this diff Show More