Merge pull request #13589 from JPVenson/feature/DatabaseRefactor

[Feature] Database code refactor
This commit is contained in:
Cody Robibero 2025-03-25 21:34:26 -06:00 committed by GitHub
commit d848faeb75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
390 changed files with 3646 additions and 1548 deletions

View file

@ -1,6 +1,8 @@
{
"name": "Development Jellyfin Server",
"image":"mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
"image": "mcr.microsoft.com/devcontainers/dotnet:9.0-bookworm",
"service": "app",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
// restores nuget packages, installs the dotnet workloads and installs the dev https certificate
"postStartCommand": "sudo dotnet restore; sudo dotnet workload update; sudo dotnet dev-certs https --trust; sudo bash \"./.devcontainer/install-ffmpeg.sh\"",
// reads the extensions list and installs them
@ -13,7 +15,9 @@
},
"ghcr.io/devcontainers-contrib/features/apt-packages:1": {
"preserve_apt_list": false,
"packages": ["libfontconfig1"]
"packages": [
"libfontconfig1"
]
},
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"dockerDashComposeVersion": "v2"

3
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,3 @@
{
"dotnet.preferVisualStudioCodeFileSystemWatcher": true
}

View file

@ -35,11 +35,11 @@ using Emby.Server.Implementations.SyncPlay;
using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates;
using Jellyfin.Api.Helpers;
using Jellyfin.Database.Implementations;
using Jellyfin.Drawing;
using Jellyfin.MediaEncoding.Hls.Playlist;
using Jellyfin.Networking.Manager;
using Jellyfin.Networking.Udp;
using Jellyfin.Server.Implementations;
using Jellyfin.Server.Implementations.Item;
using Jellyfin.Server.Implementations.MediaSegments;
using MediaBrowser.Common;
@ -574,10 +574,15 @@ namespace Emby.Server.Implementations
/// <summary>
/// Create services registered with the service container that need to be initialized at application startup.
/// </summary>
/// <param name="startupConfig">The configuration used to initialise the application.</param>
/// <returns>A task representing the service initialization operation.</returns>
public async Task InitializeServices()
public async Task InitializeServices(IConfiguration startupConfig)
{
var jellyfinDb = await Resolve<IDbContextFactory<JellyfinDbContext>>().CreateDbContextAsync().ConfigureAwait(false);
var factory = Resolve<IDbContextFactory<JellyfinDbContext>>();
var provider = Resolve<IJellyfinDatabaseProvider>();
provider.DbContextFactory = factory;
var jellyfinDb = await factory.CreateDbContextAsync().ConfigureAwait(false);
await using (jellyfinDb.ConfigureAwait(false))
{
if ((await jellyfinDb.Database.GetPendingMigrationsAsync().ConfigureAwait(false)).Any())

View file

@ -4,7 +4,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Entities;

View file

@ -4,7 +4,7 @@ using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Server.Implementations;
using Jellyfin.Database.Implementations;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;

View file

@ -5,8 +5,8 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Common;
using MediaBrowser.Controller.Channels;

View file

@ -18,6 +18,7 @@
<ProjectReference Include="..\Emby.Photos\Emby.Photos.csproj" />
<ProjectReference Include="..\src\Jellyfin.Drawing\Jellyfin.Drawing.csproj" />
<ProjectReference Include="..\MediaBrowser.MediaEncoding\MediaBrowser.MediaEncoding.csproj" />
<ProjectReference Include="..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
</ItemGroup>
<ItemGroup>

View file

@ -5,8 +5,8 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Events;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;

View file

@ -1,7 +1,8 @@
#pragma warning disable CS1591
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Data;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Net;
using Microsoft.AspNetCore.Http;

View file

@ -2,6 +2,7 @@
using System.Collections.Generic;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;

View file

@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;

View file

@ -2,6 +2,7 @@
using System.Collections.Generic;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;

View file

@ -4,6 +4,7 @@
using System.Collections.Generic;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;

View file

@ -18,8 +18,10 @@ using Emby.Server.Implementations.Library.Validators;
using Emby.Server.Implementations.Playlists;
using Emby.Server.Implementations.ScheduledTasks.Tasks;
using Emby.Server.Implementations.Sorting;
using Jellyfin.Data.Entities;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;

View file

@ -13,8 +13,10 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using AsyncKeyedLock;
using Jellyfin.Data.Entities;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using Jellyfin.Extensions.Json;
using MediaBrowser.Common.Configuration;

View file

@ -3,7 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Model.Entities;

View file

@ -4,8 +4,9 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -3,8 +3,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -6,9 +6,9 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using Jellyfin.Server.Implementations;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -6,8 +6,10 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Jellyfin.Data.Entities;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Collections;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;

View file

@ -9,8 +9,8 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -3,8 +3,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json.Serialization;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Common;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Playlists;

View file

@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Server.Implementations;
using Jellyfin.Database.Implementations;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Tasks;
using Microsoft.EntityFrameworkCore;
@ -18,6 +18,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
private readonly ILogger<OptimizeDatabaseTask> _logger;
private readonly ILocalizationManager _localization;
private readonly IDbContextFactory<JellyfinDbContext> _provider;
private readonly IJellyfinDatabaseProvider _jellyfinDatabaseProvider;
/// <summary>
/// Initializes a new instance of the <see cref="OptimizeDatabaseTask" /> class.
@ -25,14 +26,17 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
/// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
/// <param name="provider">Instance of the <see cref="IDbContextFactory{JellyfinDbContext}"/> interface.</param>
/// <param name="jellyfinDatabaseProvider">Instance of the JellyfinDatabaseProvider that can be used for provider specific operations.</param>
public OptimizeDatabaseTask(
ILogger<OptimizeDatabaseTask> logger,
ILocalizationManager localization,
IDbContextFactory<JellyfinDbContext> provider)
IDbContextFactory<JellyfinDbContext> provider,
IJellyfinDatabaseProvider jellyfinDatabaseProvider)
{
_logger = logger;
_localization = localization;
_provider = provider;
_jellyfinDatabaseProvider = jellyfinDatabaseProvider;
}
/// <inheritdoc />
@ -73,20 +77,7 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
try
{
var context = await _provider.CreateDbContextAsync(cancellationToken).ConfigureAwait(false);
await using (context.ConfigureAwait(false))
{
if (context.Database.IsSqlite())
{
await context.Database.ExecuteSqlRawAsync("PRAGMA optimize", cancellationToken).ConfigureAwait(false);
await context.Database.ExecuteSqlRawAsync("VACUUM", cancellationToken).ConfigureAwait(false);
_logger.LogInformation("jellyfin.db optimized successfully!");
}
else
{
_logger.LogInformation("This database doesn't support optimization");
}
}
await _jellyfinDatabaseProvider.RunScheduledOptimisation(cancellationToken).ConfigureAwait(false);
}
catch (Exception e)
{

View file

@ -7,11 +7,13 @@ using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Entities.Security;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Data.Events;
using Jellyfin.Data.Queries;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Entities.Security;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;

View file

@ -2,8 +2,8 @@
#pragma warning disable CS1591
using System;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Sorting;

View file

@ -1,8 +1,8 @@
#nullable disable
using System;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Sorting;

View file

@ -1,8 +1,8 @@
#nullable disable
#pragma warning disable CS1591
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Sorting;

View file

@ -2,8 +2,8 @@
#pragma warning disable CS1591
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Sorting;

View file

@ -2,8 +2,8 @@
#pragma warning disable CS1591
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Sorting;

View file

@ -1,7 +1,7 @@
#nullable disable
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Sorting;

View file

@ -5,7 +5,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Session;

View file

@ -3,8 +3,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Jellyfin.Data.Entities;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;

View file

@ -3,7 +3,8 @@ using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Data.Enums;
using Jellyfin.Data;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Net;
using Microsoft.AspNetCore.Authentication;

View file

@ -1,7 +1,8 @@
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Data.Enums;
using Jellyfin.Data;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;

View file

@ -1,6 +1,7 @@
using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.SyncPlay;

View file

@ -1,5 +1,6 @@
using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Data;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Library;

View file

@ -1,5 +1,5 @@
using Jellyfin.Api.Auth.DefaultAuthorizationPolicy;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Api.Auth.UserPermissionPolicy
{

View file

@ -4,8 +4,9 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Dto;

View file

@ -4,8 +4,8 @@ using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using Jellyfin.Api.Helpers;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller;
using MediaBrowser.Model.Dto;

View file

@ -4,8 +4,9 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -130,7 +130,7 @@ public class ImageController : BaseJellyfinApiController
await _userManager.ClearProfileImageAsync(user).ConfigureAwait(false);
}
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + extension));
user.ProfileImage = new Database.Implementations.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + extension));
await _providerManager
.SaveImage(stream, mimeType, user.ProfileImage.Path)

View file

@ -6,7 +6,7 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -4,7 +4,9 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Dto;

View file

@ -11,8 +11,9 @@ using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.LibraryDtos;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Api;
using MediaBrowser.Common.Extensions;

View file

@ -15,6 +15,7 @@ using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Api.Models.LiveTvDtos;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Api;
using MediaBrowser.Common.Configuration;

View file

@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;

View file

@ -5,8 +5,9 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;

View file

@ -4,8 +4,9 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -4,7 +4,7 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -5,7 +5,7 @@ using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;

View file

@ -3,8 +3,8 @@ using System.ComponentModel.DataAnnotations;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -3,8 +3,9 @@ using System.ComponentModel.DataAnnotations;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -1,6 +1,7 @@
using System;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;

View file

@ -7,6 +7,7 @@ using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -7,7 +7,8 @@ using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.UserDtos;
using Jellyfin.Data.Enums;
using Jellyfin.Data;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Api;
using MediaBrowser.Common.Extensions;

View file

@ -7,8 +7,8 @@ using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -6,8 +6,9 @@ using System.Linq;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.ModelBinders;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Entities;

View file

@ -8,8 +8,8 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;

View file

@ -7,8 +7,10 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Data.Entities;
using Jellyfin.Data;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;

View file

@ -5,8 +5,9 @@ using System.Security.Claims;
using System.Threading.Tasks;
using Jellyfin.Api.Constants;
using Jellyfin.Api.Extensions;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Dto;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Text.Json.Serialization;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;

View file

@ -1,7 +1,8 @@
using System;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Data;
using Jellyfin.Data.Events;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Activity;

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Jellyfin.Data.Enums;
using Jellyfin.Data;
using Jellyfin.Database.Implementations.Enums;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;

View file

@ -1,7 +1,7 @@
#pragma warning disable CS1591
using System;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Enums;
namespace Jellyfin.Data
{

View file

@ -1,33 +0,0 @@
namespace Jellyfin.Data.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
}
}

View file

@ -1,18 +0,0 @@
namespace Jellyfin.Data.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
}
}

View file

@ -1,58 +0,0 @@
namespace Jellyfin.Data.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
}
}

View file

@ -1,58 +0,0 @@
namespace Jellyfin.Data.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
}
}

View file

@ -1,23 +0,0 @@
namespace Jellyfin.Data.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
}
}

View file

@ -1,33 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// An enum representing the type of media file.
/// </summary>
public enum MediaFileKind
{
/// <summary>
/// The main file.
/// </summary>
Main = 0,
/// <summary>
/// A sidecar file.
/// </summary>
Sidecar = 1,
/// <summary>
/// An additional part to the main file.
/// </summary>
AdditionalPart = 2,
/// <summary>
/// An alternative format to the main file.
/// </summary>
AlternativeFormat = 3,
/// <summary>
/// An additional stream for the main file.
/// </summary>
AdditionalStream = 4
}
}

View file

@ -1,128 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// The types of user permissions.
/// </summary>
public enum PermissionKind
{
/// <summary>
/// Whether the user is an administrator.
/// </summary>
IsAdministrator = 0,
/// <summary>
/// Whether the user is hidden.
/// </summary>
IsHidden = 1,
/// <summary>
/// Whether the user is disabled.
/// </summary>
IsDisabled = 2,
/// <summary>
/// Whether the user can control shared devices.
/// </summary>
EnableSharedDeviceControl = 3,
/// <summary>
/// Whether the user can access the server remotely.
/// </summary>
EnableRemoteAccess = 4,
/// <summary>
/// Whether the user can manage live tv.
/// </summary>
EnableLiveTvManagement = 5,
/// <summary>
/// Whether the user can access live tv.
/// </summary>
EnableLiveTvAccess = 6,
/// <summary>
/// Whether the user can play media.
/// </summary>
EnableMediaPlayback = 7,
/// <summary>
/// Whether the server should transcode audio for the user if requested.
/// </summary>
EnableAudioPlaybackTranscoding = 8,
/// <summary>
/// Whether the server should transcode video for the user if requested.
/// </summary>
EnableVideoPlaybackTranscoding = 9,
/// <summary>
/// Whether the user can delete content.
/// </summary>
EnableContentDeletion = 10,
/// <summary>
/// Whether the user can download content.
/// </summary>
EnableContentDownloading = 11,
/// <summary>
/// Whether to enable sync transcoding for the user.
/// </summary>
EnableSyncTranscoding = 12,
/// <summary>
/// Whether the user can do media conversion.
/// </summary>
EnableMediaConversion = 13,
/// <summary>
/// Whether the user has access to all devices.
/// </summary>
EnableAllDevices = 14,
/// <summary>
/// Whether the user has access to all channels.
/// </summary>
EnableAllChannels = 15,
/// <summary>
/// Whether the user has access to all folders.
/// </summary>
EnableAllFolders = 16,
/// <summary>
/// Whether to enable public sharing for the user.
/// </summary>
EnablePublicSharing = 17,
/// <summary>
/// Whether the user can remotely control other users.
/// </summary>
EnableRemoteControlOfOtherUsers = 18,
/// <summary>
/// Whether the user is permitted to do playback remuxing.
/// </summary>
EnablePlaybackRemuxing = 19,
/// <summary>
/// Whether the server should force transcoding on remote connections for the user.
/// </summary>
ForceRemoteSourceTranscoding = 20,
/// <summary>
/// Whether the user can create, modify and delete collections.
/// </summary>
EnableCollectionManagement = 21,
/// <summary>
/// Whether the user can edit subtitles.
/// </summary>
EnableSubtitleManagement = 22,
/// <summary>
/// Whether the user can edit lyrics.
/// </summary>
EnableLyricManagement = 23,
}
}

View file

@ -1,68 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// An enum representing a person's role in a specific media item.
/// </summary>
public enum PersonRoleType
{
/// <summary>
/// Another role, not covered by the other types.
/// </summary>
Other = 0,
/// <summary>
/// The director of the media.
/// </summary>
Director = 1,
/// <summary>
/// An artist.
/// </summary>
Artist = 2,
/// <summary>
/// The original artist.
/// </summary>
OriginalArtist = 3,
/// <summary>
/// An actor.
/// </summary>
Actor = 4,
/// <summary>
/// A voice actor.
/// </summary>
VoiceActor = 5,
/// <summary>
/// A producer.
/// </summary>
Producer = 6,
/// <summary>
/// A remixer.
/// </summary>
Remixer = 7,
/// <summary>
/// A conductor.
/// </summary>
Conductor = 8,
/// <summary>
/// A composer.
/// </summary>
Composer = 9,
/// <summary>
/// An author.
/// </summary>
Author = 10,
/// <summary>
/// An editor.
/// </summary>
Editor = 11
}
}

View file

@ -1,73 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// The types of user preferences.
/// </summary>
public enum PreferenceKind
{
/// <summary>
/// A list of blocked tags.
/// </summary>
BlockedTags = 0,
/// <summary>
/// A list of blocked channels.
/// </summary>
BlockedChannels = 1,
/// <summary>
/// A list of blocked media folders.
/// </summary>
BlockedMediaFolders = 2,
/// <summary>
/// A list of enabled devices.
/// </summary>
EnabledDevices = 3,
/// <summary>
/// A list of enabled channels.
/// </summary>
EnabledChannels = 4,
/// <summary>
/// A list of enabled folders.
/// </summary>
EnabledFolders = 5,
/// <summary>
/// A list of folders to allow content deletion from.
/// </summary>
EnableContentDeletionFromFolders = 6,
/// <summary>
/// A list of latest items to exclude.
/// </summary>
LatestItemExcludes = 7,
/// <summary>
/// A list of media to exclude.
/// </summary>
MyMediaExcludes = 8,
/// <summary>
/// A list of grouped folders.
/// </summary>
GroupedFolders = 9,
/// <summary>
/// A list of unrated items to block.
/// </summary>
BlockUnratedItems = 10,
/// <summary>
/// A list of ordered views.
/// </summary>
OrderedViews = 11,
/// <summary>
/// A list of allowed tags.
/// </summary>
AllowedTags = 12
}
}

View file

@ -1,18 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// An enum representing the axis that should be scrolled.
/// </summary>
public enum ScrollDirection
{
/// <summary>
/// Horizontal scrolling direction.
/// </summary>
Horizontal = 0,
/// <summary>
/// Vertical scrolling direction.
/// </summary>
Vertical = 1
}
}

View file

@ -1,18 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// An enum representing the sorting order.
/// </summary>
public enum SortOrder
{
/// <summary>
/// Sort in increasing order.
/// </summary>
Ascending = 0,
/// <summary>
/// Sort in decreasing order.
/// </summary>
Descending = 1
}
}

View file

@ -1,33 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// An enum representing a subtitle playback mode.
/// </summary>
public enum SubtitlePlaybackMode
{
/// <summary>
/// The default subtitle playback mode.
/// </summary>
Default = 0,
/// <summary>
/// Always show subtitles.
/// </summary>
Always = 1,
/// <summary>
/// Only show forced subtitles.
/// </summary>
OnlyForced = 2,
/// <summary>
/// Don't show subtitles.
/// </summary>
None = 3,
/// <summary>
/// Only show subtitles when the current audio stream is in a different language.
/// </summary>
Smart = 4
}
}

View file

@ -1,23 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// Enum SyncPlayUserAccessType.
/// </summary>
public enum SyncPlayUserAccessType
{
/// <summary>
/// User can create groups and join them.
/// </summary>
CreateAndJoinGroups = 0,
/// <summary>
/// User can only join already existing groups.
/// </summary>
JoinGroups = 1,
/// <summary>
/// SyncPlay is disabled for the user.
/// </summary>
None = 2
}
}

View file

@ -1,113 +0,0 @@
namespace Jellyfin.Data.Enums
{
/// <summary>
/// An enum representing the type of view for a library or collection.
/// </summary>
public enum ViewType
{
/// <summary>
/// Shows albums.
/// </summary>
Albums = 0,
/// <summary>
/// Shows album artists.
/// </summary>
AlbumArtists = 1,
/// <summary>
/// Shows artists.
/// </summary>
Artists = 2,
/// <summary>
/// Shows channels.
/// </summary>
Channels = 3,
/// <summary>
/// Shows collections.
/// </summary>
Collections = 4,
/// <summary>
/// Shows episodes.
/// </summary>
Episodes = 5,
/// <summary>
/// Shows favorites.
/// </summary>
Favorites = 6,
/// <summary>
/// Shows genres.
/// </summary>
Genres = 7,
/// <summary>
/// Shows guide.
/// </summary>
Guide = 8,
/// <summary>
/// Shows movies.
/// </summary>
Movies = 9,
/// <summary>
/// Shows networks.
/// </summary>
Networks = 10,
/// <summary>
/// Shows playlists.
/// </summary>
Playlists = 11,
/// <summary>
/// Shows programs.
/// </summary>
Programs = 12,
/// <summary>
/// Shows recordings.
/// </summary>
Recordings = 13,
/// <summary>
/// Shows schedule.
/// </summary>
Schedule = 14,
/// <summary>
/// Shows series.
/// </summary>
Series = 15,
/// <summary>
/// Shows shows.
/// </summary>
Shows = 16,
/// <summary>
/// Shows songs.
/// </summary>
Songs = 17,
/// <summary>
/// Shows songs.
/// </summary>
Suggestions = 18,
/// <summary>
/// Shows trailers.
/// </summary>
Trailers = 19,
/// <summary>
/// Shows upcoming.
/// </summary>
Upcoming = 20
}
}

View file

@ -1,4 +1,4 @@
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{

View file

@ -1,4 +1,4 @@
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{

View file

@ -1,4 +1,4 @@
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{

View file

@ -1,4 +1,4 @@
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{

View file

@ -1,4 +1,4 @@
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
namespace Jellyfin.Data.Events.Users
{

View file

@ -1,18 +0,0 @@
namespace Jellyfin.Data.Interfaces
{
/// <summary>
/// An interface abstracting an entity that has a concurrency token.
/// </summary>
public interface IHasConcurrencyToken
{
/// <summary>
/// Gets the version of this row. Acts as a concurrency token.
/// </summary>
uint RowVersion { get; }
/// <summary>
/// Called when saving changes to this entity.
/// </summary>
void OnSavingChanges();
}
}

View file

@ -1,31 +0,0 @@
using System.Collections.Generic;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
namespace Jellyfin.Data.Interfaces
{
/// <summary>
/// An abstraction representing an entity that has permissions.
/// </summary>
public interface IHasPermissions
{
/// <summary>
/// Gets a collection containing this entity's permissions.
/// </summary>
ICollection<Permission> Permissions { get; }
/// <summary>
/// Checks whether this entity has the specified permission kind.
/// </summary>
/// <param name="kind">The kind of permission.</param>
/// <returns><c>true</c> if this entity has the specified permission, <c>false</c> otherwise.</returns>
bool HasPermission(PermissionKind kind);
/// <summary>
/// Sets the specified permission to the provided value.
/// </summary>
/// <param name="kind">The kind of permission.</param>
/// <param name="value">The value to set.</param>
void SetPermission(PermissionKind kind, bool value);
}
}

View file

@ -1,16 +0,0 @@
using System.Collections.Generic;
using Jellyfin.Data.Entities.Libraries;
namespace Jellyfin.Data.Interfaces
{
/// <summary>
/// An abstraction representing an entity that has releases.
/// </summary>
public interface IHasReleases
{
/// <summary>
/// Gets a collection containing this entity's releases.
/// </summary>
ICollection<Release> Releases { get; }
}
}

View file

@ -38,6 +38,10 @@
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" />
</ItemGroup>

View file

@ -0,0 +1,220 @@
using System;
using System.ComponentModel;
using System.Linq;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Database.Implementations.Interfaces;
namespace Jellyfin.Data;
/// <summary>
/// Contains extension methods for manipulation of <see cref="User"/> entities.
/// </summary>
public static class UserEntityExtensions
{
/// <summary>
/// The values being delimited here are Guids, so commas work as they do not appear in Guids.
/// </summary>
private const char Delimiter = ',';
/// <summary>
/// Checks whether the user has the specified permission.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="kind">The permission kind.</param>
/// <returns><c>True</c> if the user has the specified permission.</returns>
public static bool HasPermission(this IHasPermissions entity, PermissionKind kind)
{
return entity.Permissions.FirstOrDefault(p => p.Kind == kind)?.Value ?? false;
}
/// <summary>
/// Sets the given permission kind to the provided value.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="kind">The permission kind.</param>
/// <param name="value">The value to set.</param>
public static void SetPermission(this IHasPermissions entity, PermissionKind kind, bool value)
{
var currentPermission = entity.Permissions.FirstOrDefault(p => p.Kind == kind);
if (currentPermission is null)
{
entity.Permissions.Add(new Permission(kind, value));
}
else
{
currentPermission.Value = value;
}
}
/// <summary>
/// Gets the user's preferences for the given preference kind.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <returns>A string array containing the user's preferences.</returns>
public static string[] GetPreference(this User entity, PreferenceKind preference)
{
var val = entity.Preferences.FirstOrDefault(p => p.Kind == preference)?.Value;
return string.IsNullOrEmpty(val) ? Array.Empty<string>() : val.Split(Delimiter);
}
/// <summary>
/// Gets the user's preferences for the given preference kind.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <typeparam name="T">Type of preference.</typeparam>
/// <returns>A {T} array containing the user's preference.</returns>
public static T[] GetPreferenceValues<T>(this User entity, PreferenceKind preference)
{
var val = entity.Preferences.FirstOrDefault(p => p.Kind == preference)?.Value;
if (string.IsNullOrEmpty(val))
{
return Array.Empty<T>();
}
// Convert array of {string} to array of {T}
var converter = TypeDescriptor.GetConverter(typeof(T));
var stringValues = val.Split(Delimiter);
var convertedCount = 0;
var parsedValues = new T[stringValues.Length];
for (var i = 0; i < stringValues.Length; i++)
{
try
{
var parsedValue = converter.ConvertFromString(stringValues[i].Trim());
if (parsedValue is not null)
{
parsedValues[convertedCount++] = (T)parsedValue;
}
}
catch (FormatException)
{
// Unable to convert value
}
}
return parsedValues[..convertedCount];
}
/// <summary>
/// Sets the specified preference to the given value.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <param name="values">The values.</param>
public static void SetPreference(this User entity, PreferenceKind preference, string[] values)
{
var value = string.Join(Delimiter, values);
var currentPreference = entity.Preferences.FirstOrDefault(p => p.Kind == preference);
if (currentPreference is null)
{
entity.Preferences.Add(new Preference(preference, value));
}
else
{
currentPreference.Value = value;
}
}
/// <summary>
/// Sets the specified preference to the given value.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="preference">The preference kind.</param>
/// <param name="values">The values.</param>
/// <typeparam name="T">The type of value.</typeparam>
public static void SetPreference<T>(this User entity, PreferenceKind preference, T[] values)
{
var value = string.Join(Delimiter, values);
var currentPreference = entity.Preferences.FirstOrDefault(p => p.Kind == preference);
if (currentPreference is null)
{
entity.Preferences.Add(new Preference(preference, value));
}
else
{
currentPreference.Value = value;
}
}
/// <summary>
/// Checks whether this user is currently allowed to use the server.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <returns><c>True</c> if the current time is within an access schedule, or there are no access schedules.</returns>
public static bool IsParentalScheduleAllowed(this User entity)
{
return entity.AccessSchedules.Count == 0
|| entity.AccessSchedules.Any(i => IsParentalScheduleAllowed(i, DateTime.UtcNow));
}
/// <summary>
/// Checks whether the provided folder is in this user's grouped folders.
/// </summary>
/// <param name="entity">The entity to update.</param>
/// <param name="id">The Guid of the folder.</param>
/// <returns><c>True</c> if the folder is in the user's grouped folders.</returns>
public static bool IsFolderGrouped(this User entity, Guid id)
{
return Array.IndexOf(GetPreferenceValues<Guid>(entity, PreferenceKind.GroupedFolders), id) != -1;
}
/// <summary>
/// Initializes the default permissions for a user. Should only be called on user creation.
/// </summary>
/// <param name="entity">The entity to update.</param>
// TODO: make these user configurable?
public static void AddDefaultPermissions(this User entity)
{
entity.Permissions.Add(new Permission(PermissionKind.IsAdministrator, false));
entity.Permissions.Add(new Permission(PermissionKind.IsDisabled, false));
entity.Permissions.Add(new Permission(PermissionKind.IsHidden, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAllChannels, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAllDevices, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAllFolders, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableContentDeletion, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableContentDownloading, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableMediaConversion, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableMediaPlayback, true));
entity.Permissions.Add(new Permission(PermissionKind.EnablePlaybackRemuxing, true));
entity.Permissions.Add(new Permission(PermissionKind.EnablePublicSharing, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableRemoteAccess, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableSyncTranscoding, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableAudioPlaybackTranscoding, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableLiveTvAccess, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableLiveTvManagement, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableSharedDeviceControl, true));
entity.Permissions.Add(new Permission(PermissionKind.EnableVideoPlaybackTranscoding, true));
entity.Permissions.Add(new Permission(PermissionKind.ForceRemoteSourceTranscoding, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableRemoteControlOfOtherUsers, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableCollectionManagement, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableSubtitleManagement, false));
entity.Permissions.Add(new Permission(PermissionKind.EnableLyricManagement, false));
}
/// <summary>
/// Initializes the default preferences. Should only be called on user creation.
/// </summary>
/// <param name="entity">The entity to update.</param>
public static void AddDefaultPreferences(this User entity)
{
foreach (var val in Enum.GetValues<PreferenceKind>())
{
entity.Preferences.Add(new Preference(val, string.Empty));
}
}
private static bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date)
{
var localTime = date.ToLocalTime();
var hour = localTime.TimeOfDay.TotalHours;
var currentDayOfWeek = localTime.DayOfWeek;
return schedule.DayOfWeek.Contains(currentDayOfWeek)
&& hour >= schedule.StartHour
&& hour <= schedule.EndHour;
}
}

View file

@ -1,9 +1,10 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Events;
using Jellyfin.Data.Queries;
using Jellyfin.Database.Implementations;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Querying;
using Microsoft.EntityFrameworkCore;

View file

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Common.Configuration;
namespace Jellyfin.Server.Implementations.DatabaseConfiguration;
/// <summary>
/// Factory for constructing a database configuration.
/// </summary>
public class DatabaseConfigurationFactory : IConfigurationFactory
{
/// <inheritdoc/>
public IEnumerable<ConfigurationStore> GetConfigurations()
{
yield return new DatabaseConfigurationStore();
}
}

View file

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using Jellyfin.Database.Implementations.DbConfiguration;
using MediaBrowser.Common.Configuration;
namespace Jellyfin.Server.Implementations.DatabaseConfiguration;
/// <summary>
/// A configuration that stores database related settings.
/// </summary>
public class DatabaseConfigurationStore : ConfigurationStore
{
/// <summary>
/// The name of the configuration in the storage.
/// </summary>
public const string StoreKey = "database";
/// <summary>
/// Initializes a new instance of the <see cref="DatabaseConfigurationStore"/> class.
/// </summary>
public DatabaseConfigurationStore()
{
ConfigurationType = typeof(DatabaseConfigurationOptions);
Key = StoreKey;
}
}

View file

@ -3,12 +3,14 @@ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Jellyfin.Data;
using Jellyfin.Data.Dtos;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Entities.Security;
using Jellyfin.Data.Enums;
using Jellyfin.Data.Events;
using Jellyfin.Data.Queries;
using Jellyfin.Database.Implementations;
using Jellyfin.Database.Implementations.Entities;
using Jellyfin.Database.Implementations.Entities.Security;
using Jellyfin.Database.Implementations.Enums;
using Jellyfin.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Devices;

View file

@ -1,7 +1,7 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Events;

View file

@ -1,7 +1,7 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Events;

View file

@ -1,7 +1,7 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.Events.Authentication;
using MediaBrowser.Model.Activity;

View file

@ -1,6 +1,6 @@
using System.Globalization;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.Events.Authentication;
using MediaBrowser.Model.Activity;

View file

@ -1,8 +1,8 @@
using System;
using System.Globalization;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Enums;
using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller.Events;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Activity;

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