Merge remote-tracking branch 'upstream/master' into access-control

This commit is contained in:
ConfusedPolarBear 2020-05-18 14:27:51 -05:00
commit 3a61c9a878
227 changed files with 8613 additions and 10378 deletions

View File

@ -13,7 +13,7 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
max_line_length = null
max_line_length = off
# YAML indentation
[*.{yml,yaml}]
@ -22,6 +22,7 @@ indent_size = 2
# XML indentation
[*.{csproj,xml}]
indent_size = 2
###############################
# .NET Coding Conventions #
###############################
@ -51,11 +52,12 @@ dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
dotnet_prefer_inferred_tuple_names = true:suggestion
dotnet_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
###############################
# Naming Conventions #
###############################
@ -67,7 +69,7 @@ dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.symbols = non
dotnet_naming_rule.non_private_static_fields_should_be_pascal_case.style = non_private_static_field_style
dotnet_naming_symbols.non_private_static_fields.applicable_kinds = field
dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected internal, private protected
dotnet_naming_symbols.non_private_static_fields.applicable_accessibilities = public, protected, internal, protected_internal, private_protected
dotnet_naming_symbols.non_private_static_fields.required_modifiers = static
dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case
@ -159,6 +161,7 @@ csharp_style_deconstructed_variable_declaration = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_pattern_local_over_anonymous_function = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
###############################
# C# Formatting Rules #
###############################
@ -189,9 +192,3 @@ csharp_space_between_method_call_empty_parameter_list_parentheses = false
# Wrapping preferences
csharp_preserve_single_line_statements = true
csharp_preserve_single_line_blocks = true
###############################
# VB Coding Conventions #
###############################
[*.vb]
# Modifier preferences
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion

View File

@ -2,7 +2,7 @@ ARG DOTNET_VERSION=3.1
FROM node:alpine as web-builder
ARG JELLYFIN_WEB_VERSION=master
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm \
RUN apk add curl git zlib zlib-dev autoconf g++ make libpng-dev gifsicle alpine-sdk automake libtool make gcc musl-dev nasm python \
&& curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& cd jellyfin-web-* \
&& yarn install \

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System.Buffers.Binary;
using System.IO;

View File

@ -13,6 +13,7 @@
<TargetFramework>netstandard2.1</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
</Project>

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System.IO;
namespace DvdLib.Ifo

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System.IO;
namespace DvdLib.Ifo

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System.IO;
namespace DvdLib.Ifo

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
namespace DvdLib.Ifo
{
public class Chapter

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.IO;

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System;
namespace DvdLib.Ifo

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System.Collections.Generic;
namespace DvdLib.Ifo

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System.Collections.Generic;
using System.IO;
using System.Linq;

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System.Collections.Generic;
using System.IO;

View File

@ -1,3 +1,5 @@
#pragma warning disable CS1591
using System;
namespace DvdLib.Ifo

View File

@ -908,7 +908,8 @@ namespace Emby.Dlna.PlayTo
return 0;
}
public Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken)
/// <inheritdoc />
public Task SendMessage<T>(string name, Guid messageId, T data, CancellationToken cancellationToken)
{
if (_disposed)
{
@ -924,10 +925,12 @@ namespace Emby.Dlna.PlayTo
{
return SendPlayCommand(data as PlayRequest, cancellationToken);
}
if (string.Equals(name, "PlayState", StringComparison.OrdinalIgnoreCase))
{
return SendPlaystateCommand(data as PlaystateRequest, cancellationToken);
}
if (string.Equals(name, "GeneralCommand", StringComparison.OrdinalIgnoreCase))
{
return SendGeneralCommand(data as GeneralCommand, cancellationToken);

View File

@ -227,7 +227,7 @@ namespace Emby.Naming.Video
}
return remainingFiles
.Where(i => i.ExtraType == null)
.Where(i => i.ExtraType != null)
.Where(i => baseNames.Any(b =>
i.FileNameWithoutExtension.StartsWith(b, StringComparison.OrdinalIgnoreCase)))
.ToList();

View File

@ -89,14 +89,14 @@ namespace Emby.Naming.Video
if (parseName)
{
var cleanDateTimeResult = CleanDateTime(name);
name = cleanDateTimeResult.Name;
year = cleanDateTimeResult.Year;
if (extraResult.ExtraType == null
&& TryCleanString(cleanDateTimeResult.Name, out ReadOnlySpan<char> newName))
&& TryCleanString(name, out ReadOnlySpan<char> newName))
{
name = newName.ToString();
}
year = cleanDateTimeResult.Year;
}
return new VideoFileInfo

View File

@ -4,11 +4,10 @@ using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Jellyfin.Data.Entities;
using MediaBrowser.Common.Plugins;
using MediaBrowser.Common.Updates;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
@ -30,7 +29,7 @@ namespace Emby.Server.Implementations.Activity
/// </summary>
public sealed class ActivityLogEntryPoint : IServerEntryPoint
{
private readonly ILogger _logger;
private readonly ILogger<ActivityLogEntryPoint> _logger;
private readonly IInstallationManager _installationManager;
private readonly ISessionManager _sessionManager;
private readonly ITaskManager _taskManager;
@ -38,14 +37,12 @@ namespace Emby.Server.Implementations.Activity
private readonly ILocalizationManager _localization;
private readonly ISubtitleManager _subManager;
private readonly IUserManager _userManager;
private readonly IDeviceManager _deviceManager;
/// <summary>
/// Initializes a new instance of the <see cref="ActivityLogEntryPoint"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="sessionManager">The session manager.</param>
/// <param name="deviceManager">The device manager.</param>
/// <param name="taskManager">The task manager.</param>
/// <param name="activityManager">The activity manager.</param>
/// <param name="localization">The localization manager.</param>
@ -55,7 +52,6 @@ namespace Emby.Server.Implementations.Activity
public ActivityLogEntryPoint(
ILogger<ActivityLogEntryPoint> logger,
ISessionManager sessionManager,
IDeviceManager deviceManager,
ITaskManager taskManager,
IActivityManager activityManager,
ILocalizationManager localization,
@ -65,7 +61,6 @@ namespace Emby.Server.Implementations.Activity
{
_logger = logger;
_sessionManager = sessionManager;
_deviceManager = deviceManager;
_taskManager = taskManager;
_activityManager = activityManager;
_localization = localization;
@ -99,52 +94,38 @@ namespace Emby.Server.Implementations.Activity
_userManager.UserPolicyUpdated += OnUserPolicyUpdated;
_userManager.UserLockedOut += OnUserLockedOut;
_deviceManager.CameraImageUploaded += OnCameraImageUploaded;
return Task.CompletedTask;
}
private void OnCameraImageUploaded(object sender, GenericEventArgs<CameraImageUploadInfo> e)
private async void OnUserLockedOut(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("CameraImageUploadedFrom"),
e.Argument.Device.Name),
Type = NotificationType.CameraImageUploaded.ToString()
});
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserLockedOutWithName"),
e.Argument.Name),
NotificationType.UserLockedOut.ToString(),
e.Argument.Id))
.ConfigureAwait(false);
}
private void OnUserLockedOut(object sender, GenericEventArgs<User> e)
private async void OnSubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserLockedOutWithName"),
e.Argument.Name),
Type = NotificationType.UserLockedOut.ToString(),
UserId = e.Argument.Id
});
}
private void OnSubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("SubtitleDownloadFailureFromForItem"),
e.Provider,
Notifications.NotificationEntryPoint.GetItemName(e.Item)),
Type = "SubtitleDownloadFailure",
"SubtitleDownloadFailure",
Guid.Empty)
{
ItemId = e.Item.Id.ToString("N", CultureInfo.InvariantCulture),
ShortOverview = e.Exception.Message
});
}).ConfigureAwait(false);
}
private void OnPlaybackStopped(object sender, PlaybackStopEventArgs e)
private async void OnPlaybackStopped(object sender, PlaybackStopEventArgs e)
{
var item = e.MediaInfo;
@ -167,20 +148,19 @@ namespace Emby.Server.Implementations.Activity
var user = e.Users[0];
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"),
user.Name,
GetItemName(item),
e.DeviceName),
Type = GetPlaybackStoppedNotificationType(item.MediaType),
UserId = user.Id
});
GetPlaybackStoppedNotificationType(item.MediaType),
user.Id))
.ConfigureAwait(false);
}
private void OnPlaybackStart(object sender, PlaybackProgressEventArgs e)
private async void OnPlaybackStart(object sender, PlaybackProgressEventArgs e)
{
var item = e.MediaInfo;
@ -203,17 +183,16 @@ namespace Emby.Server.Implementations.Activity
var user = e.Users.First();
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserStartedPlayingItemWithValues"),
user.Name,
GetItemName(item),
e.DeviceName),
Type = GetPlaybackNotificationType(item.MediaType),
UserId = user.Id
});
GetPlaybackNotificationType(item.MediaType),
user.Id))
.ConfigureAwait(false);
}
private static string GetItemName(BaseItemDto item)
@ -263,7 +242,7 @@ namespace Emby.Server.Implementations.Activity
return null;
}
private void OnSessionEnded(object sender, SessionEventArgs e)
private async void OnSessionEnded(object sender, SessionEventArgs e)
{
var session = e.SessionInfo;
@ -272,110 +251,108 @@ namespace Emby.Server.Implementations.Activity
return;
}
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserOfflineFromDevice"),
session.UserName,
session.DeviceName),
Type = "SessionEnded",
"SessionEnded",
session.UserId)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("LabelIpAddressValue"),
session.RemoteEndPoint),
UserId = session.UserId
});
}).ConfigureAwait(false);
}
private void OnAuthenticationSucceeded(object sender, GenericEventArgs<AuthenticationResult> e)
private async void OnAuthenticationSucceeded(object sender, GenericEventArgs<AuthenticationResult> e)
{
var user = e.Argument.User;
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("AuthenticationSucceededWithUserName"),
user.Name),
Type = "AuthenticationSucceeded",
"AuthenticationSucceeded",
user.Id)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("LabelIpAddressValue"),
e.Argument.SessionInfo.RemoteEndPoint),
UserId = user.Id
});
}).ConfigureAwait(false);
}
private void OnAuthenticationFailed(object sender, GenericEventArgs<AuthenticationRequest> e)
private async void OnAuthenticationFailed(object sender, GenericEventArgs<AuthenticationRequest> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("FailedLoginAttemptWithUserName"),
e.Argument.Username),
Type = "AuthenticationFailed",
"AuthenticationFailed",
Guid.Empty)
{
LogSeverity = LogLevel.Error,
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("LabelIpAddressValue"),
e.Argument.RemoteEndPoint),
Severity = LogLevel.Error
});
}).ConfigureAwait(false);
}
private void OnUserPolicyUpdated(object sender, GenericEventArgs<User> e)
private async void OnUserPolicyUpdated(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserPolicyUpdatedWithName"),
e.Argument.Name),
Type = "UserPolicyUpdated",
UserId = e.Argument.Id
});
"UserPolicyUpdated",
e.Argument.Id))
.ConfigureAwait(false);
}
private void OnUserDeleted(object sender, GenericEventArgs<User> e)
private async void OnUserDeleted(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserDeletedWithName"),
e.Argument.Name),
Type = "UserDeleted"
});
"UserDeleted",
Guid.Empty))
.ConfigureAwait(false);
}
private void OnUserPasswordChanged(object sender, GenericEventArgs<User> e)
private async void OnUserPasswordChanged(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserPasswordChangedWithName"),
e.Argument.Name),
Type = "UserPasswordChanged",
UserId = e.Argument.Id
});
"UserPasswordChanged",
e.Argument.Id))
.ConfigureAwait(false);
}
private void OnUserCreated(object sender, GenericEventArgs<User> e)
private async void OnUserCreated(object sender, GenericEventArgs<MediaBrowser.Controller.Entities.User> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserCreatedWithName"),
e.Argument.Name),
Type = "UserCreated",
UserId = e.Argument.Id
});
"UserCreated",
e.Argument.Id))
.ConfigureAwait(false);
}
private void OnSessionStarted(object sender, SessionEventArgs e)
private async void OnSessionStarted(object sender, SessionEventArgs e)
{
var session = e.SessionInfo;
@ -384,87 +361,90 @@ namespace Emby.Server.Implementations.Activity
return;
}
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("UserOnlineFromDevice"),
session.UserName,
session.DeviceName),
Type = "SessionStarted",
"SessionStarted",
session.UserId)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("LabelIpAddressValue"),
session.RemoteEndPoint),
UserId = session.UserId
});
session.RemoteEndPoint)
}).ConfigureAwait(false);
}
private void OnPluginUpdated(object sender, GenericEventArgs<(IPlugin, VersionInfo)> e)
private async void OnPluginUpdated(object sender, GenericEventArgs<(IPlugin, VersionInfo)> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("PluginUpdatedWithName"),
e.Argument.Item1.Name),
Type = NotificationType.PluginUpdateInstalled.ToString(),
NotificationType.PluginUpdateInstalled.ToString(),
Guid.Empty)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("VersionNumber"),
e.Argument.Item2.version),
Overview = e.Argument.Item2.changelog
});
}).ConfigureAwait(false);
}
private void OnPluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
private async void OnPluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("PluginUninstalledWithName"),
e.Argument.Name),
Type = NotificationType.PluginUninstalled.ToString()
});
NotificationType.PluginUninstalled.ToString(),
Guid.Empty))
.ConfigureAwait(false);
}
private void OnPluginInstalled(object sender, GenericEventArgs<VersionInfo> e)
private async void OnPluginInstalled(object sender, GenericEventArgs<VersionInfo> e)
{
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("PluginInstalledWithName"),
e.Argument.name),
Type = NotificationType.PluginInstalled.ToString(),
NotificationType.PluginInstalled.ToString(),
Guid.Empty)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("VersionNumber"),
e.Argument.version)
});
}).ConfigureAwait(false);
}
private void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
private async void OnPackageInstallationFailed(object sender, InstallationFailedEventArgs e)
{
var installationInfo = e.InstallationInfo;
CreateLogEntry(new ActivityLogEntry
{
Name = string.Format(
await CreateLogEntry(new ActivityLog(
string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("NameInstallFailed"),
installationInfo.Name),
Type = NotificationType.InstallationFailed.ToString(),
NotificationType.InstallationFailed.ToString(),
Guid.Empty)
{
ShortOverview = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("VersionNumber"),
installationInfo.Version),
Overview = e.Exception.Message
});
}).ConfigureAwait(false);
}
private void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
private async void OnTaskCompleted(object sender, TaskCompletionEventArgs e)
{
var result = e.Result;
var task = e.Task;
@ -495,22 +475,20 @@ namespace Emby.Server.Implementations.Activity
vals.Add(e.Result.LongErrorMessage);
}
CreateLogEntry(new ActivityLogEntry
await CreateLogEntry(new ActivityLog(
string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
NotificationType.TaskFailed.ToString(),
Guid.Empty)
{
Name = string.Format(
CultureInfo.InvariantCulture,
_localization.GetLocalizedString("ScheduledTaskFailedWithName"),
task.Name),
Type = NotificationType.TaskFailed.ToString(),
LogSeverity = LogLevel.Error,
Overview = string.Join(Environment.NewLine, vals),
ShortOverview = runningTime,
Severity = LogLevel.Error
});
ShortOverview = runningTime
}).ConfigureAwait(false);
}
}
private void CreateLogEntry(ActivityLogEntry entry)
=> _activityManager.Create(entry);
private async Task CreateLogEntry(ActivityLog entry)
=> await _activityManager.CreateAsync(entry).ConfigureAwait(false);
/// <inheritdoc />
public void Dispose()
@ -537,8 +515,6 @@ namespace Emby.Server.Implementations.Activity
_userManager.UserDeleted -= OnUserDeleted;
_userManager.UserPolicyUpdated -= OnUserPolicyUpdated;
_userManager.UserLockedOut -= OnUserLockedOut;
_deviceManager.CameraImageUploaded -= OnCameraImageUploaded;
}
/// <summary>
@ -566,7 +542,7 @@ namespace Emby.Server.Implementations.Activity
{
int months = days / DaysInMonth;
values.Add(CreateValueString(months, "month"));
days %= DaysInMonth;
days = days % DaysInMonth;
}
// Number of days

View File

@ -1,70 +0,0 @@
using System;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.Activity
{
/// <summary>
/// The activity log manager.
/// </summary>
public class ActivityManager : IActivityManager
{
private readonly IActivityRepository _repo;
private readonly IUserManager _userManager;
/// <summary>
/// Initializes a new instance of the <see cref="ActivityManager"/> class.
/// </summary>
/// <param name="repo">The activity repository.</param>
/// <param name="userManager">The user manager.</param>
public ActivityManager(IActivityRepository repo, IUserManager userManager)
{
_repo = repo;
_userManager = userManager;
}
/// <inheritdoc />
public event EventHandler<GenericEventArgs<ActivityLogEntry>> EntryCreated;
public void Create(ActivityLogEntry entry)
{
entry.Date = DateTime.UtcNow;
_repo.Create(entry);
EntryCreated?.Invoke(this, new GenericEventArgs<ActivityLogEntry>(entry));
}
/// <inheritdoc />
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
{
var result = _repo.GetActivityLogEntries(minDate, hasUserId, startIndex, limit);
foreach (var item in result.Items)
{
if (item.UserId == Guid.Empty)
{
continue;
}
var user = _userManager.GetUserById(item.UserId);
if (user != null)
{
var dto = _userManager.GetUserDto(user);
item.UserPrimaryImageTag = dto.PrimaryImageTag;
}
}
return result;
}
/// <inheritdoc />
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit)
{
return GetActivityLogEntries(minDate, null, startIndex, limit);
}
}
}

View File

@ -1,308 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using Emby.Server.Implementations.Data;
using MediaBrowser.Controller;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Querying;
using Microsoft.Extensions.Logging;
using SQLitePCL.pretty;
namespace Emby.Server.Implementations.Activity
{
/// <summary>
/// The activity log repository.
/// </summary>
public class ActivityRepository : BaseSqliteRepository, IActivityRepository
{
private const string BaseActivitySelectText = "select Id, Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity from ActivityLog";
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="ActivityRepository"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="appPaths">The server application paths.</param>
/// <param name="fileSystem">The filesystem.</param>
public ActivityRepository(ILogger<ActivityRepository> logger, IServerApplicationPaths appPaths, IFileSystem fileSystem)
: base(logger)
{
DbFilePath = Path.Combine(appPaths.DataPath, "activitylog.db");
_fileSystem = fileSystem;
}
/// <summary>
/// Initializes the <see cref="ActivityRepository"/>.
/// </summary>
public void Initialize()
{
try
{
InitializeInternal();
}
catch (Exception ex)
{
Logger.LogError(ex, "Error loading database file. Will reset and retry.");
_fileSystem.DeleteFile(DbFilePath);
InitializeInternal();
}
}
private void InitializeInternal()
{
using var connection = GetConnection();
connection.RunQueries(new[]
{
"create table if not exists ActivityLog (Id INTEGER PRIMARY KEY, Name TEXT NOT NULL, Overview TEXT, ShortOverview TEXT, Type TEXT NOT NULL, ItemId TEXT, UserId TEXT, DateCreated DATETIME NOT NULL, LogSeverity TEXT NOT NULL)",
"drop index if exists idx_ActivityLogEntries"
});
TryMigrate(connection);
}
private void TryMigrate(ManagedConnection connection)
{
try
{
if (TableExists(connection, "ActivityLogEntries"))
{
connection.RunQueries(new[]
{
"INSERT INTO ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) SELECT Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity FROM ActivityLogEntries",
"drop table if exists ActivityLogEntries"
});
}
}
catch (Exception ex)
{
Logger.LogError(ex, "Error migrating activity log database");
}
}
/// <inheritdoc />
public void Create(ActivityLogEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
using var connection = GetConnection();
connection.RunInTransaction(db =>
{
using var statement = db.PrepareStatement("insert into ActivityLog (Name, Overview, ShortOverview, Type, ItemId, UserId, DateCreated, LogSeverity) values (@Name, @Overview, @ShortOverview, @Type, @ItemId, @UserId, @DateCreated, @LogSeverity)");
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}, TransactionMode);
}
/// <summary>
/// Adds the provided <see cref="ActivityLogEntry"/> to this repository.
/// </summary>
/// <param name="entry">The activity log entry.</param>
/// <exception cref="ArgumentNullException">If entry is null.</exception>
public void Update(ActivityLogEntry entry)
{
if (entry == null)
{
throw new ArgumentNullException(nameof(entry));
}
using var connection = GetConnection();
connection.RunInTransaction(db =>
{
using var statement = db.PrepareStatement("Update ActivityLog set Name=@Name,Overview=@Overview,ShortOverview=@ShortOverview,Type=@Type,ItemId=@ItemId,UserId=@UserId,DateCreated=@DateCreated,LogSeverity=@LogSeverity where Id=@Id");
statement.TryBind("@Id", entry.Id);
statement.TryBind("@Name", entry.Name);
statement.TryBind("@Overview", entry.Overview);
statement.TryBind("@ShortOverview", entry.ShortOverview);
statement.TryBind("@Type", entry.Type);
statement.TryBind("@ItemId", entry.ItemId);
if (entry.UserId.Equals(Guid.Empty))
{
statement.TryBindNull("@UserId");
}
else
{
statement.TryBind("@UserId", entry.UserId.ToString("N", CultureInfo.InvariantCulture));
}
statement.TryBind("@DateCreated", entry.Date.ToDateTimeParamValue());
statement.TryBind("@LogSeverity", entry.Severity.ToString());
statement.MoveNext();
}, TransactionMode);
}
/// <inheritdoc />
public QueryResult<ActivityLogEntry> GetActivityLogEntries(DateTime? minDate, bool? hasUserId, int? startIndex, int? limit)
{
var commandText = BaseActivitySelectText;
var whereClauses = new List<string>();
if (minDate.HasValue)
{
whereClauses.Add("DateCreated>=@DateCreated");
}
if (hasUserId.HasValue)
{
whereClauses.Add(hasUserId.Value ? "UserId not null" : "UserId is null");
}
var whereTextWithoutPaging = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
if (startIndex.HasValue && startIndex.Value > 0)
{
var pagingWhereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
whereClauses.Add(
string.Format(
CultureInfo.InvariantCulture,
"Id NOT IN (SELECT Id FROM ActivityLog {0} ORDER BY DateCreated DESC LIMIT {1})",
pagingWhereText,
startIndex.Value));
}
var whereText = whereClauses.Count == 0 ?
string.Empty :
" where " + string.Join(" AND ", whereClauses.ToArray());
commandText += whereText;
commandText += " ORDER BY DateCreated DESC";
if (limit.HasValue)
{
commandText += " LIMIT " + limit.Value.ToString(CultureInfo.InvariantCulture);
}
var statementTexts = new[]
{
commandText,
"select count (Id) from ActivityLog" + whereTextWithoutPaging
};
var list = new List<ActivityLogEntry>();
var result = new QueryResult<ActivityLogEntry>();
using var connection = GetConnection(true);
connection.RunInTransaction(
db =>
{
var statements = PrepareAll(db, statementTexts).ToList();
using (var statement = statements[0])
{
if (minDate.HasValue)
{
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
list.AddRange(statement.ExecuteQuery().Select(GetEntry));
}
using (var statement = statements[1])
{
if (minDate.HasValue)
{
statement.TryBind("@DateCreated", minDate.Value.ToDateTimeParamValue());
}
result.TotalRecordCount = statement.ExecuteQuery().SelectScalarInt().First();
}
},
ReadTransactionMode);
result.Items = list;
return result;
}
private static ActivityLogEntry GetEntry(IReadOnlyList<IResultSetValue> reader)
{
var index = 0;
var info = new ActivityLogEntry
{
Id = reader[index].ToInt64()
};
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Name = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Overview = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.ShortOverview = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Type = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.ItemId = reader[index].ToString();
}
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.UserId = new Guid(reader[index].ToString());
}
index++;
info.Date = reader[index].ReadDateTime();
index++;
if (reader[index].SQLiteType != SQLiteType.Null)
{
info.Severity = Enum.Parse<LogLevel>(reader[index].ToString(), true);
}
return info;
}
}
}

View File

@ -22,7 +22,6 @@ using Emby.Dlna.Ssdp;
using Emby.Drawing;
using Emby.Notifications;
using Emby.Photos;
using Emby.Server.Implementations.Activity;
using Emby.Server.Implementations.Archiving;
using Emby.Server.Implementations.Channels;
using Emby.Server.Implementations.Collections;
@ -44,7 +43,6 @@ using Emby.Server.Implementations.Security;
using Emby.Server.Implementations.Serialization;
using Emby.Server.Implementations.Services;
using Emby.Server.Implementations.Session;
using Emby.Server.Implementations.SocketSharp;
using Emby.Server.Implementations.TV;
using Emby.Server.Implementations.Updates;
using MediaBrowser.Api;
@ -82,7 +80,6 @@ using MediaBrowser.Controller.Subtitles;
using MediaBrowser.Controller.TV;
using MediaBrowser.LocalMetadata.Savers;
using MediaBrowser.MediaEncoding.BdInfo;
using MediaBrowser.Model.Activity;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Cryptography;
using MediaBrowser.Model.Dlna;
@ -94,7 +91,6 @@ using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Updates;
using MediaBrowser.Providers.Chapters;
using MediaBrowser.Providers.Manager;
using MediaBrowser.Providers.Plugins.TheTvdb;
@ -102,11 +98,10 @@ using MediaBrowser.Providers.Subtitles;
using MediaBrowser.WebDashboard.Api;
using MediaBrowser.XbmcMetadata.Providers;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
using Prometheus.DotNetRuntime;
using OperatingSystem = MediaBrowser.Common.System.OperatingSystem;
namespace Emby.Server.Implementations
{
@ -503,32 +498,8 @@ namespace Emby.Server.Implementations
RegisterServices(serviceCollection);
}
public async Task ExecuteWebsocketHandlerAsync(HttpContext context, Func<Task> next)
{
if (!context.WebSockets.IsWebSocketRequest)
{
await next().ConfigureAwait(false);
return;
}
await _httpServer.ProcessWebSocketRequest(context).ConfigureAwait(false);
}
public async Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
{
if (context.WebSockets.IsWebSocketRequest)
{
await next().ConfigureAwait(false);
return;
}
var request = context.Request;
var response = context.Response;
var localPath = context.Request.Path.ToString();
var req = new WebSocketSharpRequest(request, response, request.Path, LoggerFactory.CreateLogger<WebSocketSharpRequest>());
await _httpServer.RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted).ConfigureAwait(false);
}
public Task ExecuteHttpHandlerAsync(HttpContext context, Func<Task> next)
=> _httpServer.RequestHandler(context);
/// <summary>
/// Registers services/resources with the service collection that will be available via DI.
@ -546,13 +517,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IJsonSerializer, JsonSerializer>();
// TODO: Remove support for injecting ILogger completely
serviceCollection.AddSingleton((provider) =>
{
Logger.LogWarning("Injecting ILogger directly is deprecated and should be replaced with ILogger<T>");
return Logger;
});
serviceCollection.AddSingleton(_fileSystemManager);
serviceCollection.AddSingleton<TvdbClientManager>();
@ -621,7 +585,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<ISearchEngine, SearchEngine>();
serviceCollection.AddSingleton<ServiceController>();
serviceCollection.AddSingleton<IHttpListener, WebSocketSharpListener>();
serviceCollection.AddSingleton<IHttpServer, HttpListenerHost>();
serviceCollection.AddSingleton<IImageProcessor, ImageProcessor>();
@ -663,9 +626,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>();
serviceCollection.AddSingleton<IActivityRepository, ActivityRepository>();
serviceCollection.AddSingleton<IActivityManager, ActivityManager>();
serviceCollection.AddSingleton<IAuthorizationContext, AuthorizationContext>();
serviceCollection.AddSingleton<ISessionContext, SessionContext>();
@ -696,7 +656,6 @@ namespace Emby.Server.Implementations
((SqliteDisplayPreferencesRepository)Resolve<IDisplayPreferencesRepository>()).Initialize();
((AuthenticationRepository)Resolve<IAuthenticationRepository>()).Initialize();
((SqliteUserRepository)Resolve<IUserRepository>()).Initialize();
((ActivityRepository)Resolve<IActivityRepository>()).Initialize();
SetStaticProperties();
@ -1150,9 +1109,6 @@ namespace Emby.Server.Implementations
ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
CachePath = ApplicationPaths.CachePath,
HttpServerPortNumber = HttpPort,
SupportsHttps = SupportsHttps,
HttpsPortNumber = HttpsPort,
OperatingSystem = OperatingSystem.Id.ToString(),
OperatingSystemDisplayName = OperatingSystem.Name,
CanSelfRestart = CanSelfRestart,
@ -1188,23 +1144,22 @@ namespace Emby.Server.Implementations
};
}
public bool EnableHttps => SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps;
/// <inheritdoc/>
public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.Configuration.EnableHttps;
public bool SupportsHttps => Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy;
public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp = false)
/// <inheritdoc/>
public async Task<string> GetLocalApiUrl(CancellationToken cancellationToken)
{
try
{
// Return the first matched address, if found, or the first known local address
var addresses = await GetLocalIpAddressesInternal(false, 1, cancellationToken).ConfigureAwait(false);
foreach (var address in addresses)
if (addresses.Count == 0)
{
return GetLocalApiUrl(address, forceHttp);
return null;
}
return null;
return GetLocalApiUrl(addresses.First());
}
catch (Exception ex)
{
@ -1231,7 +1186,7 @@ namespace Emby.Server.Implementations
}
/// <inheritdoc />
public string GetLocalApiUrl(IPAddress ipAddress, bool forceHttp = false)
public string GetLocalApiUrl(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
@ -1241,29 +1196,30 @@ namespace Emby.Server.Implementations
str.CopyTo(span.Slice(1));
span[^1] = ']';
return GetLocalApiUrl(span, forceHttp);
return GetLocalApiUrl(span);
}
return GetLocalApiUrl(ipAddress.ToString(), forceHttp);
return GetLocalApiUrl(ipAddress.ToString());
}
/// <inheritdoc />
public string GetLocalApiUrl(ReadOnlySpan<char> host, bool forceHttp = false)
/// <inheritdoc/>
public string GetLoopbackHttpApiUrl()
{
var url = new StringBuilder(64);
bool useHttps = EnableHttps && !forceHttp;
url.Append(useHttps ? "https://" : "http://")
.Append(host)
.Append(':')
.Append(useHttps ? HttpsPort : HttpPort);
return GetLocalApiUrl("127.0.0.1", Uri.UriSchemeHttp, HttpPort);
}
string baseUrl = ServerConfigurationManager.Configuration.BaseUrl;
if (baseUrl.Length != 0)
/// <inheritdoc/>
public string GetLocalApiUrl(ReadOnlySpan<char> host, string scheme = null, int? port = null)
{
// NOTE: If no BaseUrl is set then UriBuilder appends a trailing slash, but if there is no BaseUrl it does
// not. For consistency, always trim the trailing slash.
return new UriBuilder
{
url.Append(baseUrl);
}
return url.ToString();
Scheme = scheme ?? (ListenWithHttps ? Uri.UriSchemeHttps : Uri.UriSchemeHttp),
Host = host.ToString(),
Port = port ?? (ListenWithHttps ? HttpsPort : HttpPort),
Path = ServerConfigurationManager.Configuration.BaseUrl
}.ToString().TrimEnd('/');
}
public Task<List<IPAddress>> GetLocalIpAddresses(CancellationToken cancellationToken)
@ -1297,7 +1253,7 @@ namespace Emby.Server.Implementations
}
}
var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
var valid = await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
if (valid)
{
resultList.Add(address);
@ -1331,7 +1287,7 @@ namespace Emby.Server.Implementations
private readonly ConcurrentDictionary<string, bool> _validAddressResults = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
private async Task<bool> IsIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken)
private async Task<bool> IsLocalIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken)
{
if (address.Equals(IPAddress.Loopback)
|| address.Equals(IPAddress.IPv6Loopback))
@ -1339,8 +1295,7 @@ namespace Emby.Server.Implementations
return true;
}
var apiUrl = GetLocalApiUrl(address);
apiUrl += "/system/ping";
var apiUrl = GetLocalApiUrl(address) + "/system/ping";
if (_validAddressResults.TryGetValue(apiUrl, out var cachedResult))
{

View File

@ -31,18 +31,18 @@ namespace Emby.Server.Implementations.Browser
/// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored.
/// </summary>
/// <param name="appHost">The application host.</param>
/// <param name="url">The URL.</param>
private static void TryOpenUrl(IServerApplicationHost appHost, string url)
/// <param name="relativeUrl">The URL to open, relative to the server base URL.</param>
private static void TryOpenUrl(IServerApplicationHost appHost, string relativeUrl)
{
try
{
string baseUrl = appHost.GetLocalApiUrl("localhost");
appHost.LaunchUrl(baseUrl + url);
appHost.LaunchUrl(baseUrl + relativeUrl);
}
catch (Exception ex)
{
var logger = appHost.Resolve<ILogger>();
logger?.LogError(ex, "Failed to open browser window with URL {URL}", url);
logger?.LogError(ex, "Failed to open browser window with URL {URL}", relativeUrl);
}
}
}

View File

@ -193,12 +193,6 @@ namespace Emby.Server.Implementations.Configuration
changed = true;
}
if (!config.CameraUploadUpgraded)
{
config.CameraUploadUpgraded = true;
changed = true;
}
if (!config.CollectionsUpgraded)
{
config.CollectionsUpgraded = true;

View File

@ -1,7 +1,6 @@
using System.Collections.Generic;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.Updates;
using MediaBrowser.Providers.Music;
using static MediaBrowser.Controller.Extensions.ConfigurationExtensions;
namespace Emby.Server.Implementations

View File

@ -375,5 +375,15 @@ namespace Emby.Server.Implementations.Data
return userData;
}
/// <inheritdoc/>
/// <remarks>
/// There is nothing to dispose here since <see cref="BaseSqliteRepository.WriteLock"/> and
/// <see cref="BaseSqliteRepository.WriteConnection"/> are managed by <see cref="SqliteItemRepository"/>.
/// See <see cref="Initialize(IUserManager, SemaphoreSlim, SQLiteDatabaseConnection)"/>.
/// </remarks>
protected override void Dispose(bool dispose)
{
}
}
}

View File

@ -5,27 +5,18 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
using MediaBrowser.Model.Users;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Devices
{
@ -33,38 +24,23 @@ namespace Emby.Server.Implementations.Devices
{
private readonly IJsonSerializer _json;
private readonly IUserManager _userManager;
private readonly IFileSystem _fileSystem;
private readonly ILibraryMonitor _libraryMonitor;
private readonly IServerConfigurationManager _config;
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _localizationManager;
private readonly IAuthenticationRepository _authRepo;
private readonly Dictionary<string, ClientCapabilities> _capabilitiesCache;
public event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
public event EventHandler<GenericEventArgs<CameraImageUploadInfo>> CameraImageUploaded;
private readonly object _cameraUploadSyncLock = new object();
private readonly object _capabilitiesSyncLock = new object();
public DeviceManager(
IAuthenticationRepository authRepo,
IJsonSerializer json,
ILibraryManager libraryManager,
ILocalizationManager localizationManager,
IUserManager userManager,
IFileSystem fileSystem,
ILibraryMonitor libraryMonitor,
IServerConfigurationManager config)
{
_json = json;
_userManager = userManager;
_fileSystem = fileSystem;
_libraryMonitor = libraryMonitor;
_config = config;
_libraryManager = libraryManager;
_localizationManager = localizationManager;
_authRepo = authRepo;
_capabilitiesCache = new Dictionary<string, ClientCapabilities>(StringComparer.OrdinalIgnoreCase);
}
@ -194,172 +170,6 @@ namespace Emby.Server.Implementations.Devices
return Path.Combine(GetDevicesPath(), id.GetMD5().ToString("N", CultureInfo.InvariantCulture));
}
public ContentUploadHistory GetCameraUploadHistory(string deviceId)
{
var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json");
lock (_cameraUploadSyncLock)
{
try
{
return _json.DeserializeFromFile<ContentUploadHistory>(path);
}
catch (IOException)
{
return new ContentUploadHistory
{
DeviceId = deviceId
};
}
}
}
public async Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file)
{
var device = GetDevice(deviceId, false);
var uploadPathInfo = GetUploadPath(device);
var path = uploadPathInfo.Item1;
if (!string.IsNullOrWhiteSpace(file.Album))
{
path = Path.Combine(path, _fileSystem.GetValidFilename(file.Album));
}
path = Path.Combine(path, file.Name);
path = Path.ChangeExtension(path, MimeTypes.ToExtension(file.MimeType) ?? "jpg");
Directory.CreateDirectory(Path.GetDirectoryName(path));
await EnsureLibraryFolder(uploadPathInfo.Item2, uploadPathInfo.Item3).ConfigureAwait(false);
_libraryMonitor.ReportFileSystemChangeBeginning(path);
try
{
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
{
await stream.CopyToAsync(fs).ConfigureAwait(false);
}
AddCameraUpload(deviceId, file);
}
finally
{
_libraryMonitor.ReportFileSystemChangeComplete(path, true);
}
if (CameraImageUploaded != null)
{
CameraImageUploaded?.Invoke(this, new GenericEventArgs<CameraImageUploadInfo>
{
Argument = new CameraImageUploadInfo
{
Device = device,
FileInfo = file
}
});
}
}
private void AddCameraUpload(string deviceId, LocalFileInfo file)
{
var path = Path.Combine(GetDevicePath(deviceId), "camerauploads.json");
Directory.CreateDirectory(Path.GetDirectoryName(path));
lock (_cameraUploadSyncLock)
{
ContentUploadHistory history;
try
{
history = _json.DeserializeFromFile<ContentUploadHistory>(path);
}
catch (IOException)
{
history = new ContentUploadHistory
{
DeviceId = deviceId
};
}
history.DeviceId = deviceId;
var list = history.FilesUploaded.ToList();
list.Add(file);
history.FilesUploaded = list.ToArray();
_json.SerializeToFile(history, path);
}
}
internal Task EnsureLibraryFolder(string path, string name)
{
var existingFolders = _libraryManager
.RootFolder
.Children
.OfType<Folder>()
.Where(i => _fileSystem.AreEqual(path, i.Path) || _fileSystem.ContainsSubPath(i.Path, path))
.ToList();
if (existingFolders.Count > 0)
{
return Task.CompletedTask;
}
Directory.CreateDirectory(path);
var libraryOptions = new LibraryOptions
{
PathInfos = new[] { new MediaPathInfo { Path = path } },
EnablePhotos = true,
EnableRealtimeMonitor = false,
SaveLocalMetadata = true
};
if (string.IsNullOrWhiteSpace(name))
{
name = _localizationManager.GetLocalizedString("HeaderCameraUploads");
}
return _libraryManager.AddVirtualFolder(name, CollectionType.HomeVideos, libraryOptions, true);
}
private Tuple<string, string, string> GetUploadPath(DeviceInfo device)
{
var config = _config.GetUploadOptions();
var path = config.CameraUploadPath;
if (string.IsNullOrWhiteSpace(path))
{
path = DefaultCameraUploadsPath;
}
var topLibraryPath = path;
if (config.EnableCameraUploadSubfolders)
{
path = Path.Combine(path, _fileSystem.GetValidFilename(device.Name));
}
return new Tuple<string, string, string>(path, topLibraryPath, null);
}
internal string GetUploadsPath()
{
var config = _config.GetUploadOptions();
var path = config.CameraUploadPath;
if (string.IsNullOrWhiteSpace(path))
{
path = DefaultCameraUploadsPath;
}
return path;
}
private string DefaultCameraUploadsPath => Path.Combine(_config.CommonApplicationPaths.DataPath, "camerauploads");
public bool CanAccessDevice(User user, string deviceId)
{
if (user == null)
@ -399,102 +209,4 @@ namespace Emby.Server.Implementations.Devices
return policy.EnabledDevices.Contains(id, StringComparer.OrdinalIgnoreCase);
}
}
public class DeviceManagerEntryPoint : IServerEntryPoint
{
private readonly DeviceManager _deviceManager;
private readonly IServerConfigurationManager _config;
private ILogger _logger;
public DeviceManagerEntryPoint(
IDeviceManager deviceManager,
IServerConfigurationManager config,
ILogger<DeviceManagerEntryPoint> logger)
{
_deviceManager = (DeviceManager)deviceManager;
_config = config;
_logger = logger;
}
public async Task RunAsync()
{
if (!_config.Configuration.CameraUploadUpgraded && _config.Configuration.IsStartupWizardCompleted)
{
var path = _deviceManager.GetUploadsPath();
if (Directory.Exists(path))
{
try
{
await _deviceManager.EnsureLibraryFolder(path, null).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating camera uploads library");
}
_config.Configuration.CameraUploadUpgraded = true;
_config.SaveConfiguration();
}
}
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.
disposedValue = true;
}
}
// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~DeviceManagerEntryPoint() {
// // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
// Dispose(false);
// }
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
// TODO: uncomment the following line if the finalizer is overridden above.
// GC.SuppressFinalize(this);
}
#endregion
}
public class DevicesConfigStore : IConfigurationFactory
{
public IEnumerable<ConfigurationStore> GetConfigurations()
{
return new ConfigurationStore[]
{
new ConfigurationStore
{
Key = "devices",
ConfigurationType = typeof(DevicesOptions)
}
};
}
}
public static class UploadConfigExtension
{
public static DevicesOptions GetUploadOptions(this IConfigurationManager config)
{
return config.GetConfiguration<DevicesOptions>("devices");
}
}
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<!-- ProjectGuid is only included as a requirement for SonarQube analysis -->
<PropertyGroup>
@ -34,10 +34,10 @@
<PackageReference Include="Microsoft.AspNetCore.ResponseCompression" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.WebSockets" Version="2.2.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.4" />
<PackageReference Include="Mono.Nat" Version="2.0.1" />
<PackageReference Include="prometheus-net.DotNetRuntime" Version="3.3.1" />
<PackageReference Include="ServiceStack.Text.Core" Version="5.8.0" />

View File

@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.EntryPoints
.Append(config.PublicHttpsPort).Append(Separator)
.Append(_appHost.HttpPort).Append(Separator)
.Append(_appHost.HttpsPort).Append(Separator)
.Append(_appHost.EnableHttps).Append(Separator)
.Append(_appHost.ListenWithHttps).Append(Separator)
.Append(config.EnableRemoteAccess).Append(Separator)
.ToString();
}
@ -158,7 +158,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
yield return CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort);
if (_appHost.EnableHttps)
if (_appHost.ListenWithHttps)
{
yield return CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort);
}

View File

@ -6,11 +6,12 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Net;
using Emby.Server.Implementations.Services;
using Emby.Server.Implementations.SocketSharp;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
@ -22,15 +23,17 @@ using MediaBrowser.Model.Globalization;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using ServiceStack.Text.Jsv;
namespace Emby.Server.Implementations.HttpServer
{
public class HttpListenerHost : IHttpServer, IDisposable
public class HttpListenerHost : IHttpServer
{
/// <summary>
/// The key for a setting that specifies the default redirect path
@ -39,17 +42,17 @@ namespace Emby.Server.Implementations.HttpServer
public const string DefaultRedirectKey = "HttpListenerHost:DefaultRedirectPath";
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
private readonly IServerApplicationHost _appHost;
private readonly IJsonSerializer _jsonSerializer;
private readonly IXmlSerializer _xmlSerializer;
private readonly IHttpListener _socketListener;
private readonly Func<Type, Func<string, object>> _funcParseFn;
private readonly string _defaultRedirectPath;
private readonly string _baseUrlPrefix;
private readonly Dictionary<Type, Type> _serviceOperationsMap = new Dictionary<Type, Type>();
private readonly List<IWebSocketConnection> _webSocketConnections = new List<IWebSocketConnection>();
private readonly IHostEnvironment _hostEnvironment;
private IWebSocketListener[] _webSocketListeners = Array.Empty<IWebSocketListener>();
@ -63,10 +66,10 @@ namespace Emby.Server.Implementations.HttpServer
INetworkManager networkManager,
IJsonSerializer jsonSerializer,
IXmlSerializer xmlSerializer,
IHttpListener socketListener,
ILocalizationManager localizationManager,
ServiceController serviceController,
IHostEnvironment hostEnvironment)
IHostEnvironment hostEnvironment,
ILoggerFactory loggerFactory)
{
_appHost = applicationHost;
_logger = logger;
@ -76,11 +79,9 @@ namespace Emby.Server.Implementations.HttpServer
_networkManager = networkManager;
_jsonSerializer = jsonSerializer;
_xmlSerializer = xmlSerializer;
_socketListener = socketListener;
ServiceController = serviceController;
_socketListener.WebSocketConnected = OnWebSocketConnected;
_hostEnvironment = hostEnvironment;
_loggerFactory = loggerFactory;
_funcParseFn = t => s => JsvReader.GetParseFn(t)(s);
@ -172,38 +173,6 @@ namespace Emby.Server.Implementations.HttpServer
return attributes;
}
private void OnWebSocketConnected(WebSocketConnectEventArgs e)
{
if (_disposed)
{
return;
}
var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger)
{
OnReceive = ProcessWebSocketMessageReceived,
Url = e.Url,
QueryString = e.QueryString
};
connection.Closed += OnConnectionClosed;
lock (_webSocketConnections)
{
_webSocketConnections.Add(connection);
}
WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection));
}
private void OnConnectionClosed(object sender, EventArgs e)
{
lock (_webSocketConnections)
{
_webSocketConnections.Remove((IWebSocketConnection)sender);
}
}
private static Exception GetActualException(Exception ex)
{
if (ex is AggregateException agg)
@ -241,16 +210,8 @@ namespace Emby.Server.Implementations.HttpServer
}
}
private async Task ErrorHandler(Exception ex, IRequest httpReq, int statusCode, string urlToLog)
private async Task ErrorHandler(Exception ex, IRequest httpReq, int statusCode, string urlToLog, bool ignoreStackTrace)
{
bool ignoreStackTrace =
ex is SocketException
|| ex is IOException
|| ex is OperationCanceledException
|| ex is SecurityException
|| ex is AuthenticationException
|| ex is FileNotFoundException;
if (ignoreStackTrace)
{
_logger.LogError("Error processing request: {Message}. URL: {Url}", ex.Message.TrimEnd('.'), urlToLog);
@ -289,32 +250,6 @@ namespace Emby.Server.Implementations.HttpServer
.Replace(_config.ApplicationPaths.ProgramDataPath, string.Empty, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// Shut down the Web Service
/// </summary>
public void Stop()
{
List<IWebSocketConnection> connections;
lock (_webSocketConnections)
{
connections = _webSocketConnections.ToList();
_webSocketConnections.Clear();
}
foreach (var connection in connections)
{
try
{
connection.Dispose();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error disposing connection");
}
}
}
public static string RemoveQueryStringByKey(string url, string key)
{
var uri = new Uri(url);
@ -424,33 +359,52 @@ namespace Emby.Server.Implementations.HttpServer
return true;
}
/// <summary>
/// Validate a connection from a remote IP address to a URL to see if a redirection to HTTPS is required.
/// </summary>
/// <returns>True if the request is valid, or false if the request is not valid and an HTTPS redirect is required.</returns>
private bool ValidateSsl(string remoteIp, string urlString)
{
if (_config.Configuration.RequireHttps && _appHost.EnableHttps && !_config.Configuration.IsBehindProxy)
if (_config.Configuration.RequireHttps
&& _appHost.ListenWithHttps
&& !urlString.Contains("https://", StringComparison.OrdinalIgnoreCase))
{
if (urlString.IndexOf("https://", StringComparison.OrdinalIgnoreCase) == -1)
// These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected
if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1
|| urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1)
{
// These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected
if (urlString.IndexOf("system/ping", StringComparison.OrdinalIgnoreCase) != -1
|| urlString.IndexOf("dlna/", StringComparison.OrdinalIgnoreCase) != -1)
{
return true;
}
return true;
}
if (!_networkManager.IsInLocalNetwork(remoteIp))
{
return false;
}
if (!_networkManager.IsInLocalNetwork(remoteIp))
{
return false;
}
}
return true;
}
/// <inheritdoc />
public Task RequestHandler(HttpContext context)
{
if (context.WebSockets.IsWebSocketRequest)
{
return WebSocketRequestHandler(context);
}
var request = context.Request;
var response = context.Response;
var localPath = context.Request.Path.ToString();
var req = new WebSocketSharpRequest(request, response, request.Path, _logger);
return RequestHandler(req, request.GetDisplayUrl(), request.Host.ToString(), localPath, context.RequestAborted);
}
/// <summary>
/// Overridable method that can be used to implement a custom handler.
/// </summary>
public async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken)
private async Task RequestHandler(IHttpRequest httpReq, string urlString, string host, string localPath, CancellationToken cancellationToken)
{
var stopWatch = new Stopwatch();
stopWatch.Start();
@ -493,9 +447,10 @@ namespace Emby.Server.Implementations.HttpServer
if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase))
{
httpRes.StatusCode = 200;
httpRes.Headers.Add("Access-Control-Allow-Origin", "*");
httpRes.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
httpRes.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization");
foreach(var (key, value) in GetDefaultCorsHeaders(httpReq))
{
httpRes.Headers.Add(key, value);
}
httpRes.ContentType = "text/plain";
await httpRes.WriteAsync(string.Empty, cancellationToken).ConfigureAwait(false);
return;
@ -547,14 +502,24 @@ namespace Emby.Server.Implementations.HttpServer
httpRes.Headers.Add("Access-Control-Allow-Origin", "*");
}
// Do not handle 500 server exceptions manually when in development mode
// The framework-defined development exception page will be returned instead
if (statusCode == 500 && _hostEnvironment.IsDevelopment())
bool ignoreStackTrace =
requestInnerEx is SocketException
|| requestInnerEx is IOException
|| requestInnerEx is OperationCanceledException
|| requestInnerEx is SecurityException
|| requestInnerEx is AuthenticationException
|| requestInnerEx is FileNotFoundException;
// Do not handle 500 server exceptions manually when in development mode.
// Instead, re-throw the exception so it can be handled by the DeveloperExceptionPageMiddleware.
// However, do not use the DeveloperExceptionPageMiddleware when the stack trace should be ignored,
// because it will log the stack trace when it handles the exception.
if (statusCode == 500 && !ignoreStackTrace && _hostEnvironment.IsDevelopment())
{
throw;
}
await ErrorHandler(requestInnerEx, httpReq, statusCode, urlToLog).ConfigureAwait(false);
await ErrorHandler(requestInnerEx, httpReq, statusCode, urlToLog, ignoreStackTrace).ConfigureAwait(false);
}
catch (Exception handlerException)
{
@ -583,6 +548,68 @@ namespace Emby.Server.Implementations.HttpServer
}
}
private async Task WebSocketRequestHandler(HttpContext context)
{
if (_disposed)
{
return;
}
try
{
_logger.LogInformation("WS {IP} request", context.Connection.RemoteIpAddress);
WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync().ConfigureAwait(false);
var connection = new WebSocketConnection(
_loggerFactory.CreateLogger<WebSocketConnection>(),
webSocket,
context.Connection.RemoteIpAddress,
context.Request.Query)
{
OnReceive = ProcessWebSocketMessageReceived
};
WebSocketConnected?.Invoke(this, new GenericEventArgs<IWebSocketConnection>(connection));
await connection.ProcessAsync().ConfigureAwait(false);
_logger.LogInformation("WS {IP} closed", context.Connection.RemoteIpAddress);
}
catch (Exception ex) // Otherwise ASP.Net will ignore the exception
{
_logger.LogError(ex, "WS {IP} WebSocketRequestHandler error", context.Connection.RemoteIpAddress);
if (!context.Response.HasStarted)
{
context.Response.StatusCode = 500;
}
}
}
/// <summary>
/// Get the default CORS headers
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public IDictionary<string, string> GetDefaultCorsHeaders(IRequest req)
{
var origin = req.Headers["Origin"];
if (origin == StringValues.Empty)
{
origin = req.Headers["Host"];
if (origin == StringValues.Empty)
{
origin = "*";
}
}
var headers = new Dictionary<string, string>();
headers.Add("Access-Control-Allow-Origin", origin);
headers.Add("Access-Control-Allow-Credentials", "true");
headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
headers.Add("Access-Control-Allow-Headers", "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization, Cookie");
return headers;
}
// Entry point for HttpListener
public ServiceHandler GetServiceHandler(IHttpRequest httpReq)
{
@ -629,7 +656,7 @@ namespace Emby.Server.Implementations.HttpServer
ResponseFilters = new Action<IRequest, HttpResponse, object>[]
{
new ResponseFilter(_logger).FilterResponse
new ResponseFilter(this, _logger).FilterResponse
};
}
@ -690,11 +717,6 @@ namespace Emby.Server.Implementations.HttpServer
return _jsonSerializer.DeserializeFromStreamAsync(stream, type);
}
public Task ProcessWebSocketRequest(HttpContext context)
{
return _socketListener.ProcessWebSocketRequest(context);
}
private string NormalizeEmbyRoutePath(string path)
{
_logger.LogDebug("Normalizing /emby route");
@ -713,28 +735,6 @@ namespace Emby.Server.Implementations.HttpServer
return _baseUrlPrefix + NormalizeUrlPath(path);
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
Stop();
}
_disposed = true;
}
/// <summary>
/// Processes the web socket message received.
/// </summary>
@ -746,8 +746,6 @@ namespace Emby.Server.Implementations.HttpServer
return Task.CompletedTask;
}
_logger.LogDebug("Websocket message received: {0}", result.MessageType);
IEnumerable<Task> GetTasks()
{
foreach (var x in _webSocketListeners)

View File

@ -1,39 +0,0 @@
#pragma warning disable CS1591
using System;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Net;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
namespace Emby.Server.Implementations.HttpServer
{
public interface IHttpListener : IDisposable
{
/// <summary>
/// Gets or sets the error handler.
/// </summary>
/// <value>The error handler.</value>
Func<Exception, IRequest, bool, bool, Task> ErrorHandler { get; set; }
/// <summary>
/// Gets or sets the request handler.
/// </summary>
/// <value>The request handler.</value>
Func<IHttpRequest, string, string, string, CancellationToken, Task> RequestHandler { get; set; }
/// <summary>
/// Gets or sets the web socket handler.
/// </summary>
/// <value>The web socket handler.</value>
Action<WebSocketConnectEventArgs> WebSocketConnected { get; set; }
/// <summary>
/// Stops this instance.
/// </summary>
Task Stop();
Task ProcessWebSocketRequest(HttpContext ctx);
}
}

View File

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
@ -13,14 +15,17 @@ namespace Emby.Server.Implementations.HttpServer
/// </summary>
public class ResponseFilter
{
private readonly IHttpServer _server;
private readonly ILogger _logger;
/// <summary>
/// Initializes a new instance of the <see cref="ResponseFilter"/> class.
/// </summary>
/// <param name="server">The HTTP server.</param>
/// <param name="logger">The logger.</param>
public ResponseFilter(ILogger logger)
public ResponseFilter(IHttpServer server, ILogger logger)
{
_server = server;
_logger = logger;
}
@ -32,10 +37,16 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="dto">The dto.</param>
public void FilterResponse(IRequest req, HttpResponse res, object dto)
{
foreach(var (key, value) in _server.GetDefaultCorsHeaders(req))
{
res.Headers.Add(key, value);
}
// Try to prevent compatibility view
res.Headers.Add("Access-Control-Allow-Headers", "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, X-Emby-Authorization");
res.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, PATCH, OPTIONS");
res.Headers.Add("Access-Control-Allow-Origin", "*");
res.Headers["Access-Control-Allow-Headers"] = ("Accept, Accept-Language, Authorization, Cache-Control, " +
"Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, " +
"Content-Type, Cookie, Date, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, " +
"Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-MediaBrowser-Token, " +
"X-Emby-Authorization");
if (dto is Exception exception)
{

View File

@ -1,15 +1,18 @@
using System;
#nullable enable
using System;
using System.Buffers;
using System.IO.Pipelines;
using System.Net;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Net;
using MediaBrowser.Common.Json;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using UtfUnknown;
namespace Emby.Server.Implementations.HttpServer
{
@ -24,69 +27,50 @@ namespace Emby.Server.Implementations.HttpServer
private readonly ILogger _logger;
/// <summary>
/// The json serializer.
/// The json serializer options.
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
private readonly JsonSerializerOptions _jsonOptions;
/// <summary>
/// The socket.
/// </summary>
private readonly IWebSocket _socket;
private readonly WebSocket _socket;
/// <summary>
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="socket">The socket.</param>
/// <param name="remoteEndPoint">The remote end point.</param>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="logger">The logger.</param>
/// <exception cref="ArgumentNullException">socket</exception>
public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger)
/// <param name="query">The query.</param>
public WebSocketConnection(
ILogger<WebSocketConnection> logger,
WebSocket socket,
IPAddress? remoteEndPoint,
IQueryCollection query)
{
if (socket == null)
{
throw new ArgumentNullException(nameof(socket));
}
if (string.IsNullOrEmpty(remoteEndPoint))
{
throw new ArgumentNullException(nameof(remoteEndPoint));
}
if (jsonSerializer == null)
{
throw new ArgumentNullException(nameof(jsonSerializer));
}
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
Id = Guid.NewGuid();
_jsonSerializer = jsonSerializer;
_socket = socket;
_socket.OnReceiveBytes = OnReceiveInternal;
RemoteEndPoint = remoteEndPoint;
_logger = logger;
_socket = socket;
RemoteEndPoint = remoteEndPoint;
QueryString = query;
socket.Closed += OnSocketClosed;
_jsonOptions = JsonDefaults.GetOptions();
LastActivityDate = DateTime.Now;
}
/// <inheritdoc />
public event EventHandler<EventArgs> Closed;
public event EventHandler<EventArgs>? Closed;
/// <summary>
/// Gets or sets the remote end point.
/// </summary>
public string RemoteEndPoint { get; private set; }
public IPAddress? RemoteEndPoint { get; }
/// <summary>
/// Gets or sets the receive action.
/// </summary>
/// <value>The receive action.</value>
public Func<WebSocketMessageInfo, Task> OnReceive { get; set; }
public Func<WebSocketMessageInfo, Task>? OnReceive { get; set; }
/// <summary>
/// Gets the last activity date.
@ -94,23 +78,11 @@ namespace Emby.Server.Implementations.HttpServer
/// <value>The last activity date.</value>
public DateTime LastActivityDate { get; private set; }
/// <summary>
/// Gets the id.
/// </summary>
/// <value>The id.</value>
public Guid Id { get; private set; }
/// <summary>
/// Gets or sets the URL.
/// </summary>
/// <value>The URL.</value>
public string Url { get; set; }
/// <summary>
/// Gets or sets the query string.
/// </summary>
/// <value>The query string.</value>
public IQueryCollection QueryString { get; set; }
public IQueryCollection QueryString { get; }
/// <summary>
/// Gets the state.
@ -118,70 +90,6 @@ namespace Emby.Server.Implementations.HttpServer
/// <value>The state.</value>
public WebSocketState State => _socket.State;
void OnSocketClosed(object sender, EventArgs e)
{
Closed?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Called when [receive].
/// </summary>
/// <param name="bytes">The bytes.</param>
private void OnReceiveInternal(byte[] bytes)
{
LastActivityDate = DateTime.UtcNow;
if (OnReceive == null)
{
return;
}
var charset = CharsetDetector.DetectFromBytes(bytes).Detected?.EncodingName;
if (string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase))
{
OnReceiveInternal(Encoding.UTF8.GetString(bytes, 0, bytes.Length));
}
else
{
OnReceiveInternal(Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
private void OnReceiveInternal(string message)
{
LastActivityDate = DateTime.UtcNow;
if (!message.StartsWith("{", StringComparison.OrdinalIgnoreCase))
{
// This info is useful sometimes but also clogs up the log
_logger.LogDebug("Received web socket message that is not a json structure: {message}", message);
return;
}
if (OnReceive == null)
{
return;
}
try
{
var stub = (WebSocketMessage<object>)_jsonSerializer.DeserializeFromString(message, typeof(WebSocketMessage<object>));
var info = new WebSocketMessageInfo
{
MessageType = stub.MessageType,
Data = stub.Data?.ToString(),
Connection = this
};
OnReceive(info);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing web socket message");
}
}
/// <summary>
/// Sends a message asynchronously.
/// </summary>
@ -189,67 +97,128 @@ namespace Emby.Server.Implementations.HttpServer
/// <param name="message">The message.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
/// <exception cref="ArgumentNullException">message</exception>
public Task SendAsync<T>(WebSocketMessage<T> message, CancellationToken cancellationToken)
{
if (message == null)
{
throw new ArgumentNullException(nameof(message));
}
var json = _jsonSerializer.SerializeToString(message);
return SendAsync(json, cancellationToken);
}
/// <summary>
/// Sends a message asynchronously.
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public Task SendAsync(byte[] buffer, CancellationToken cancellationToken)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
cancellationToken.ThrowIfCancellationRequested();
return _socket.SendAsync(buffer, true, cancellationToken);
var json = JsonSerializer.SerializeToUtf8Bytes(message, _jsonOptions);
return _socket.SendAsync(json, WebSocketMessageType.Text, true, cancellationToken);
}
/// <inheritdoc />
public Task SendAsync(string text, CancellationToken cancellationToken)
public async Task ProcessAsync(CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(text))
var pipe = new Pipe();
var writer = pipe.Writer;
ValueWebSocketReceiveResult receiveresult;
do
{
throw new ArgumentNullException(nameof(text));
// Allocate at least 512 bytes from the PipeWriter
Memory<byte> memory = writer.GetMemory(512);
try
{
receiveresult = await _socket.ReceiveAsync(memory, cancellationToken);
}
catch (WebSocketException ex)
{
_logger.LogWarning("WS {IP} error receiving data: {Message}", RemoteEndPoint, ex.Message);
break;
}
int bytesRead = receiveresult.Count;
if (bytesRead == 0)
{
break;
}
// Tell the PipeWriter how much was read from the Socket
writer.Advance(bytesRead);
// Make the data available to the PipeReader
FlushResult flushResult = await writer.FlushAsync();
if (flushResult.IsCompleted)
{
// The PipeReader stopped reading
break;
}
LastActivityDate = DateTime.UtcNow;
if (receiveresult.EndOfMessage)
{
await ProcessInternal(pipe.Reader).ConfigureAwait(false);
}
} while (
(_socket.State == WebSocketState.Open || _socket.State == WebSocketState.Connecting)
&& receiveresult.MessageType != WebSocketMessageType.Close);
Closed?.Invoke(this, EventArgs.Empty);
if (_socket.State == WebSocketState.Open
|| _socket.State == WebSocketState.CloseReceived
|| _socket.State == WebSocketState.CloseSent)
{
await _socket.CloseAsync(
WebSocketCloseStatus.NormalClosure,
string.Empty,
cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
return _socket.SendAsync(text, true, cancellationToken);
}
/// <inheritdoc />
public void Dispose()
private async Task ProcessInternal(PipeReader reader)
{
Dispose(true);
GC.SuppressFinalize(this);
}
ReadResult result = await reader.ReadAsync().ConfigureAwait(false);
ReadOnlySequence<byte> buffer = result.Buffer;
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
if (dispose)
if (OnReceive == null)
{
_socket.Dispose();
// Tell the PipeReader how much of the buffer we have consumed
reader.AdvanceTo(buffer.End);
return;
}
WebSocketMessage<object> stub;
try
{
if (buffer.IsSingleSegment)
{
stub = JsonSerializer.Deserialize<WebSocketMessage<object>>(buffer.FirstSpan, _jsonOptions);
}
else
{
var buf = ArrayPool<byte>.Shared.Rent(Convert.ToInt32(buffer.Length));
try
{
buffer.CopyTo(buf);
stub = JsonSerializer.Deserialize<WebSocketMessage<object>>(buf, _jsonOptions);
}
finally
{
ArrayPool<byte>.Shared.Return(buf);
}
}
}
catch (JsonException ex)
{
// Tell the PipeReader how much of the buffer we have consumed
reader.AdvanceTo(buffer.End);
_logger.LogError(ex, "Error processing web socket message");
return;
}
// Tell the PipeReader how much of the buffer we have consumed
reader.AdvanceTo(buffer.End);
_logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub);
var info = new WebSocketMessageInfo
{
MessageType = stub.MessageType,
Data = stub.Data?.ToString(), // Data can be null
Connection = this
};
await OnReceive(info).ConfigureAwait(false);
}
}
}

View File

@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
/// </summary>
public class MusicAlbumResolver : ItemResolver<MusicAlbum>
{
private readonly ILogger _logger;
private readonly ILogger<MusicAlbumResolver> _logger;
private readonly IFileSystem _fileSystem;
private readonly ILibraryManager _libraryManager;
@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
/// <param name="logger">The logger.</param>
/// <param name="fileSystem">The file system.</param>
/// <param name="libraryManager">The library manager.</param>
public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager)
public MusicAlbumResolver(ILogger<MusicAlbumResolver> logger, IFileSystem fileSystem, ILibraryManager libraryManager)
{
_logger = logger;
_fileSystem = fileSystem;

View File

@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
/// </summary>
public class MusicArtistResolver : ItemResolver<MusicArtist>
{
private readonly ILogger _logger;
private readonly ILogger<MusicAlbumResolver> _logger;
private readonly IFileSystem _fileSystem;
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _config;
@ -23,12 +23,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
/// <summary>
/// Initializes a new instance of the <see cref="MusicArtistResolver"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="logger">The logger for the created <see cref="MusicAlbumResolver"/> instances.</param>
/// <param name="fileSystem">The file system.</param>
/// <param name="libraryManager">The library manager.</param>
/// <param name="config">The configuration manager.</param>
public MusicArtistResolver(
ILogger<MusicArtistResolver> logger,
ILogger<MusicAlbumResolver> logger,
IFileSystem fileSystem,
ILibraryManager libraryManager,
IServerConfigurationManager config)

View File

@ -11,7 +11,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
{
public class BookResolver : MediaBrowser.Controller.Resolvers.ItemResolver<Book>
{
private readonly string[] _validExtensions = { ".pdf", ".epub", ".mobi", ".cbr", ".cbz", ".azw3" };
private readonly string[] _validExtensions = { ".azw", ".azw3", ".cb7", ".cbr", ".cbt", ".cbz", ".epub", ".mobi", ".opf", ".pdf" };
protected override Book Resolve(ItemResolveArgs args)
{

View File

@ -608,6 +608,31 @@ namespace Emby.Server.Implementations.Library
return dto;
}
public PublicUserDto GetPublicUserDto(User user, string remoteEndPoint = null)
{
if (user == null)
{
throw new ArgumentNullException(nameof(user));
}
IAuthenticationProvider authenticationProvider = GetAuthenticationProvider(user);
bool hasConfiguredPassword = authenticationProvider.HasPassword(user);
bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(authenticationProvider.GetEasyPasswordHash(user));
bool hasPassword = user.Configuration.EnableLocalPassword &&
!string.IsNullOrEmpty(remoteEndPoint) &&
_networkManager.IsInLocalNetwork(remoteEndPoint) ? hasConfiguredEasyPassword : hasConfiguredPassword;
PublicUserDto dto = new PublicUserDto
{
Name = user.Name,
HasPassword = hasPassword,
HasConfiguredPassword = hasConfiguredPassword,
};
return dto;
}
public UserDto GetOfflineUserDto(User user)
{
var dto = GetUserDto(user);

View File

@ -1059,7 +1059,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
var stream = new MediaSourceInfo
{
EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
EncoderPath = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
EncoderProtocol = MediaProtocol.Http,
Path = info.Path,
Protocol = MediaProtocol.File,

View File

@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Protocol = MediaProtocol.Http;
//OpenedMediaSource.SupportsDirectPlay = false;
//OpenedMediaSource.SupportsDirectStream = true;

View File

@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public M3UTunerHost(
IServerConfigurationManager config,
IMediaSourceManager mediaSourceManager,
ILogger logger,
ILogger<M3UTunerHost> logger,
IJsonSerializer jsonSerializer,
IFileSystem fileSystem,
IHttpClient httpClient,
@ -83,7 +83,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return Task.FromResult(list);
}
private static readonly string[] _disallowedSharedStreamExtensions = new string[]
private static readonly string[] _disallowedSharedStreamExtensions =
{
".mkv",
".mp4",

View File

@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Net.Http;
using System.Threading;
@ -106,7 +107,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Protocol = MediaProtocol.Http;
//OpenedMediaSource.Path = TempFilePath;
@ -118,6 +119,17 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
//OpenedMediaSource.SupportsDirectStream = true;
//OpenedMediaSource.SupportsTranscoding = true;
await taskCompletionSource.Task.ConfigureAwait(false);
if (taskCompletionSource.Task.Exception != null)
{
// Error happened while opening the stream so raise the exception again to inform the caller
throw taskCompletionSource.Task.Exception;
}
if (!taskCompletionSource.Task.Result)
{
Logger.LogWarning("Zero bytes copied from stream {0} to {1} but no exception raised", GetType().Name, TempFilePath);
throw new EndOfStreamException(String.Format(CultureInfo.InvariantCulture, "Zero bytes copied from stream {0}", GetType().Name));
}
}
private Task StartStreaming(HttpResponseInfo response, TaskCompletionSource<bool> openTaskCompletionSource, CancellationToken cancellationToken)
@ -139,14 +151,19 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
cancellationToken).ConfigureAwait(false);
}
}
catch (OperationCanceledException)
catch (OperationCanceledException ex)
{
Logger.LogInformation("Copying of {0} to {1} was canceled", GetType().Name, TempFilePath);
openTaskCompletionSource.TrySetException(ex);
}
catch (Exception ex)
{
Logger.LogError(ex, "Error copying live stream.");
Logger.LogError(ex, "Error copying live stream {0} to {1}.", GetType().Name, TempFilePath);
openTaskCompletionSource.TrySetException(ex);
}
openTaskCompletionSource.TrySetResult(false);
EnableStreamSharing = false;
await DeleteTempFiles(new List<string> { TempFilePath }).ConfigureAwait(false);
});

View File

@ -4,7 +4,7 @@
"Folders": "Fouers",
"Favorites": "Gunstelinge",
"HeaderFavoriteShows": "Gunsteling Vertonings",
"ValueSpecialEpisodeName": "Spesiaal - {0}",
"ValueSpecialEpisodeName": "Spesiale - {0}",
"HeaderAlbumArtists": "Album Kunstenaars",
"Books": "Boeke",
"HeaderNextUp": "Volgende",

View File

@ -91,5 +91,7 @@
"HeaderNextUp": "এরপরে আসছে",
"HeaderLiveTV": "লাইভ টিভি",
"HeaderFavoriteSongs": "প্রিয় গানগুলো",
"HeaderFavoriteShows": "প্রিয় শোগুলো"
"HeaderFavoriteShows": "প্রিয় শোগুলো",
"TasksLibraryCategory": "গ্রন্থাগার",
"TasksMaintenanceCategory": "রক্ষণাবেক্ষণ"
}

View File

@ -24,7 +24,7 @@
"HeaderFavoriteShows": "Programas favoritos",
"HeaderFavoriteSongs": "Canciones favoritas",
"HeaderLiveTV": "TV en vivo",
"HeaderNextUp": "A Continuación",
"HeaderNextUp": "Siguiente",
"HeaderRecordingGroups": "Grupos de grabación",
"HomeVideos": "Videos caseros",
"Inherit": "Heredar",
@ -44,7 +44,7 @@
"NameInstallFailed": "{0} instalación fallida",
"NameSeasonNumber": "Temporada {0}",
"NameSeasonUnknown": "Temporada desconocida",
"NewVersionIsAvailable": "Una nueva versión del Servidor Jellyfin está disponible para descargar.",
"NewVersionIsAvailable": "Una nueva versión del servidor Jellyfin está disponible para descargar.",
"NotificationOptionApplicationUpdateAvailable": "Actualización de la aplicación disponible",
"NotificationOptionApplicationUpdateInstalled": "Actualización de la aplicación instalada",
"NotificationOptionAudioPlayback": "Se inició la reproducción de audio",
@ -56,7 +56,7 @@
"NotificationOptionPluginInstalled": "Complemento instalado",
"NotificationOptionPluginUninstalled": "Complemento desinstalado",
"NotificationOptionPluginUpdateInstalled": "Actualización de complemento instalada",
"NotificationOptionServerRestartRequired": "Se necesita reiniciar el Servidor",
"NotificationOptionServerRestartRequired": "Se necesita reiniciar el servidor",
"NotificationOptionTaskFailed": "Falla de tarea programada",
"NotificationOptionUserLockedOut": "Usuario bloqueado",
"NotificationOptionVideoPlayback": "Se inició la reproducción de video",
@ -71,7 +71,7 @@
"ScheduledTaskFailedWithName": "{0} falló",
"ScheduledTaskStartedWithName": "{0} iniciado",
"ServerNameNeedsToBeRestarted": "{0} necesita ser reiniciado",
"Shows": "Series",
"Shows": "Programas",
"Songs": "Canciones",
"StartupEmbyServerIsLoading": "El servidor Jellyfin se está cargando. Vuelve a intentarlo en breve.",
"SubtitleDownloadFailureForItem": "Subtitles failed to download for {0}",
@ -94,25 +94,25 @@
"ValueSpecialEpisodeName": "Especial - {0}",
"VersionNumber": "Versión {0}",
"TaskDownloadMissingSubtitlesDescription": "Busca en internet los subtítulos que falten basándose en la configuración de los metadatos.",
"TaskDownloadMissingSubtitles": "Descargar subtítulos extraviados",
"TaskDownloadMissingSubtitles": "Descargar subtítulos faltantes",
"TaskRefreshChannelsDescription": "Actualizar información de canales de internet.",
"TaskRefreshChannels": "Actualizar canales",
"TaskCleanTranscodeDescription": "Eliminar archivos transcodificados con mas de un día de antigüedad.",
"TaskCleanTranscode": "Limpiar directorio de Transcodificado",
"TaskCleanTranscode": "Limpiar directorio de transcodificación",
"TaskUpdatePluginsDescription": "Descargar e instalar actualizaciones para complementos que estén configurados en actualizar automáticamente.",
"TaskUpdatePlugins": "Actualizar complementos",
"TaskRefreshPeopleDescription": "Actualizar metadatos de actores y directores en su librería multimedia.",
"TaskRefreshPeopleDescription": "Actualizar metadatos de actores y directores en su biblioteca multimedia.",
"TaskRefreshPeople": "Actualizar personas",
"TaskCleanLogsDescription": "Eliminar archivos de registro que tengan mas de {0} días de antigüedad.",
"TaskCleanLogs": "Limpiar directorio de registros",
"TaskRefreshLibraryDescription": "Escanear su librería multimedia por nuevos archivos y refrescar metadatos.",
"TaskRefreshLibrary": "Escanear librería multimedia",
"TaskRefreshLibraryDescription": "Escanear su biblioteca multimedia por nuevos archivos y refrescar metadatos.",
"TaskRefreshLibrary": "Escanear biblioteca multimedia",
"TaskRefreshChapterImagesDescription": "Crear miniaturas de videos que tengan capítulos.",
"TaskRefreshChapterImages": "Extraer imágenes de capitulo",
"TaskCleanCacheDescription": "Eliminar archivos de cache que no se necesiten en el sistema.",
"TaskCleanCache": "Limpiar directorio Cache",
"TasksChannelsCategory": "Canales de Internet",
"TasksApplicationCategory": "Solicitud",
"TaskRefreshChapterImages": "Extraer imágenes de capítulo",
"TaskCleanCacheDescription": "Eliminar archivos de caché que no se necesiten en el sistema.",
"TaskCleanCache": "Limpiar directorio caché",
"TasksChannelsCategory": "Canales de internet",
"TasksApplicationCategory": "Aplicación",
"TasksLibraryCategory": "Biblioteca",
"TasksMaintenanceCategory": "Mantenimiento"
}

View File

@ -11,7 +11,7 @@
"Collections": "Colecciones",
"DeviceOfflineWithName": "{0} se ha desconectado",
"DeviceOnlineWithName": "{0} está conectado",
"FailedLoginAttemptWithUserName": "Intento fallido de inicio de sesión de {0}",
"FailedLoginAttemptWithUserName": "Intento fallido de inicio de sesión desde {0}",
"Favorites": "Favoritos",
"Folders": "Carpetas",
"Genres": "Géneros",

View File

@ -71,7 +71,7 @@
"ScheduledTaskFailedWithName": "{0} falló",
"ScheduledTaskStartedWithName": "{0} iniciada",
"ServerNameNeedsToBeRestarted": "{0} necesita ser reiniciado",
"Shows": "Series",
"Shows": "Mostrar",
"Songs": "Canciones",
"StartupEmbyServerIsLoading": "Jellyfin Server se está cargando. Vuelve a intentarlo en breve.",
"SubtitleDownloadFailureForItem": "Error al descargar subtítulos para {0}",

View File

@ -94,5 +94,24 @@
"ValueSpecialEpisodeName": "Spécial - {0}",
"VersionNumber": "Version {0}",
"TasksLibraryCategory": "Bibliothèque",
"TasksMaintenanceCategory": "Entretien"
"TasksMaintenanceCategory": "Entretien",
"TaskDownloadMissingSubtitlesDescription": "Recherche l'internet pour des sous-titres manquants à base de métadonnées configurées.",
"TaskDownloadMissingSubtitles": "Télécharger les sous-titres manquants",
"TaskRefreshChannelsDescription": "Rafraîchit des informations des chaines internet.",
"TaskRefreshChannels": "Rafraîchir des chaines",
"TaskCleanTranscodeDescription": "Supprime les fichiers de transcodage de plus d'un jour.",
"TaskCleanTranscode": "Nettoyer le répertoire de transcodage",
"TaskUpdatePluginsDescription": "Télécharger et installer les mises à jours des extensions qui sont configurés pour les m.à.j. automisés.",
"TaskUpdatePlugins": "Mise à jour des extensions",
"TaskRefreshPeopleDescription": "Met à jour les métadonnées pour les acteurs et réalisateurs dans votre bibliothèque de médias.",
"TaskRefreshPeople": "Rafraîchir les acteurs",
"TaskCleanLogsDescription": "Supprime les journaux qui ont plus que {0} jours.",
"TaskCleanLogs": "Nettoyer le répertoire des journaux",
"TaskRefreshLibraryDescription": "Analyse votre bibliothèque média pour trouver de nouveaux fichiers et rafraîchit les métadonnées.",
"TaskRefreshChapterImages": "Extraire les images de chapitre",
"TaskRefreshChapterImagesDescription": "Créer des vignettes pour les vidéos qui ont des chapitres",
"TaskRefreshLibrary": "Analyser la bibliothèque de médias",
"TaskCleanCache": "Nettoyer le répertoire des fichiers temporaires",
"TasksApplicationCategory": "Application",
"TaskCleanCacheDescription": "Supprime les fichiers temporaires qui ne sont plus nécessaire pour le système."
}

View File

@ -1,41 +1,41 @@
{
"Albums": "Albom",
"AppDeviceValues": "App: {0}, Grät: {1}",
"Application": "Aawändig",
"Artists": "Könstler",
"AuthenticationSucceededWithUserName": "{0} het sech aagmäudet",
"Books": "Büecher",
"CameraImageUploadedFrom": "Es nöis Foti esch ufeglade worde vo {0}",
"Channels": "Kanäu",
"ChapterNameValue": "Kapitu {0}",
"Collections": "Sammlige",
"DeviceOfflineWithName": "{0} esch offline gange",
"DeviceOnlineWithName": "{0} esch online cho",
"FailedLoginAttemptWithUserName": "Fäugschlagne Aamäudeversuech vo {0}",
"Favorites": "Favorite",
"Albums": "Alben",
"AppDeviceValues": "App: {0}, Gerät: {1}",
"Application": "Anwendung",
"Artists": "Künstler",
"AuthenticationSucceededWithUserName": "{0} hat sich angemeldet",
"Books": "Bücher",
"CameraImageUploadedFrom": "Ein neues Foto wurde von {0} hochgeladen",
"Channels": "Kanäle",
"ChapterNameValue": "Kapitel {0}",
"Collections": "Sammlungen",
"DeviceOfflineWithName": "{0} wurde getrennt",
"DeviceOnlineWithName": "{0} ist verbunden",
"FailedLoginAttemptWithUserName": "Fehlgeschlagener Anmeldeversuch von {0}",
"Favorites": "Favoriten",
"Folders": "Ordner",
"Genres": "Genres",
"HeaderAlbumArtists": "Albom-Könstler",
"HeaderAlbumArtists": "Album-Künstler",
"HeaderCameraUploads": "Kamera-Uploads",
"HeaderContinueWatching": "Wiiterluege",
"HeaderFavoriteAlbums": "Lieblingsalbe",
"HeaderFavoriteArtists": "Lieblings-Interprete",
"HeaderFavoriteEpisodes": "Lieblingsepisode",
"HeaderFavoriteShows": "Lieblingsserie",
"HeaderContinueWatching": "weiter schauen",
"HeaderFavoriteAlbums": "Lieblingsalben",
"HeaderFavoriteArtists": "Lieblings-Künstler",
"HeaderFavoriteEpisodes": "Lieblingsepisoden",
"HeaderFavoriteShows": "Lieblingsserien",
"HeaderFavoriteSongs": "Lieblingslieder",
"HeaderLiveTV": "Live-Färnseh",
"HeaderNextUp": "Als nächts",
"HeaderRecordingGroups": "Ufnahmegruppe",
"HomeVideos": "Heimfilmli",
"Inherit": "Hinzuefüege",
"ItemAddedWithName": "{0} esch de Bibliothek dezuegfüegt worde",
"ItemRemovedWithName": "{0} esch vo de Bibliothek entfärnt worde",
"LabelIpAddressValue": "IP-Adrässe: {0}",
"LabelRunningTimeValue": "Loufziit: {0}",
"Latest": "Nöischti",
"MessageApplicationUpdated": "Jellyfin Server esch aktualisiert worde",
"MessageApplicationUpdatedTo": "Jellyfin Server esch of Version {0} aktualisiert worde",
"MessageNamedServerConfigurationUpdatedWithValue": "De Serveriistöuigsberiich {0} esch aktualisiert worde",
"HeaderLiveTV": "Live-Fernseh",
"HeaderNextUp": "Als Nächstes",
"HeaderRecordingGroups": "Aufnahme-Gruppen",
"HomeVideos": "Heimvideos",
"Inherit": "Vererben",
"ItemAddedWithName": "{0} wurde der Bibliothek hinzugefügt",
"ItemRemovedWithName": "{0} wurde aus der Bibliothek entfernt",
"LabelIpAddressValue": "IP-Adresse: {0}",
"LabelRunningTimeValue": "Laufzeit: {0}",
"Latest": "Neueste",
"MessageApplicationUpdated": "Jellyfin-Server wurde aktualisiert",
"MessageApplicationUpdatedTo": "Jellyfin-Server wurde auf Version {0} aktualisiert",
"MessageNamedServerConfigurationUpdatedWithValue": "Der Server-Einstellungsbereich {0} wurde aktualisiert",
"MessageServerConfigurationUpdated": "Serveriistöuige send aktualisiert worde",
"MixedContent": "Gmeschti Inhäut",
"Movies": "Film",
@ -50,7 +50,7 @@
"NotificationOptionAudioPlayback": "Audiowedergab gstartet",
"NotificationOptionAudioPlaybackStopped": "Audiwedergab gstoppt",
"NotificationOptionCameraImageUploaded": "Foti ueglade",
"NotificationOptionInstallationFailed": "Installationsfäuer",
"NotificationOptionInstallationFailed": "Installationsfehler",
"NotificationOptionNewLibraryContent": "Nöie Inhaut hinzuegfüegt",
"NotificationOptionPluginError": "Plugin-Fäuer",
"NotificationOptionPluginInstalled": "Plugin installiert",
@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} het d'Wedergab vo {1} of {2} gstoppt",
"ValueHasBeenAddedToLibrary": "{0} esch dinnere Biblithek hinzuegfüegt worde",
"ValueSpecialEpisodeName": "Extra - {0}",
"VersionNumber": "Version {0}"
"VersionNumber": "Version {0}",
"TaskCleanLogs": "Lösche Log Pfad",
"TaskRefreshLibraryDescription": "Scanne alle Bibliotheken für hinzugefügte Datein und erneuere Metadaten.",
"TaskRefreshLibrary": "Scanne alle Bibliotheken",
"TaskRefreshChapterImagesDescription": "Kreiert Vorschaubilder für Videos welche Kapitel haben.",
"TaskRefreshChapterImages": "Extrahiere Kapitel-Bilder",
"TaskCleanCacheDescription": "Löscht Zwischenspeicherdatein die nicht länger von System gebraucht werden.",
"TaskCleanCache": "Leere Cache Pfad",
"TasksChannelsCategory": "Internet Kanäle",
"TasksApplicationCategory": "Applikation",
"TasksLibraryCategory": "Bibliothek",
"TasksMaintenanceCategory": "Verwaltung",
"TaskDownloadMissingSubtitlesDescription": "Durchsucht das Internet nach fehlenden Untertiteln, basierend auf den Metadaten Einstellungen.",
"TaskDownloadMissingSubtitles": "Lade fehlende Untertitel herunter",
"TaskRefreshChannelsDescription": "Aktualisiert Internet Kanal Informationen.",
"TaskRefreshChannels": "Aktualisiere Kanäle",
"TaskCleanTranscodeDescription": "Löscht Transkodierdateien welche älter als ein Tag sind.",
"TaskCleanTranscode": "Räume Transcodier Verzeichnis auf",
"TaskUpdatePluginsDescription": "Lädt Aktualisierungen für Erweiterungen herunter und installiert diese, für welche automatische Aktualisierungen konfiguriert sind.",
"TaskUpdatePlugins": "Aktualisiere Erweiterungen",
"TaskRefreshPeopleDescription": "Aktualisiert Metadaten für Schausteller und Regisseure in deiner Bibliothek.",
"TaskRefreshPeople": "Aktualisiere Schauspieler",
"TaskCleanLogsDescription": "Löscht Log Dateien die älter als {0} Tage sind."
}

View File

@ -99,5 +99,13 @@
"TaskCleanCache": "נקה תיקיית מטמון",
"TasksApplicationCategory": "יישום",
"TasksLibraryCategory": "ספרייה",
"TasksMaintenanceCategory": "תחזוקה"
"TasksMaintenanceCategory": "תחזוקה",
"TaskUpdatePlugins": "עדכן תוספים",
"TaskRefreshPeopleDescription": "מעדכן מטא נתונים עבור שחקנים ובמאים בספריית המדיה שלך.",
"TaskRefreshPeople": "רענן אנשים",
"TaskCleanLogsDescription": "מוחק קבצי יומן בני יותר מ- {0} ימים.",
"TaskCleanLogs": "נקה תיקיית יומן",
"TaskRefreshLibraryDescription": "סורק את ספריית המדיה שלך אחר קבצים חדשים ומרענן מטא נתונים.",
"TaskRefreshChapterImagesDescription": "יוצר תמונות ממוזערות לסרטונים שיש להם פרקים.",
"TasksChannelsCategory": "ערוצי אינטרנט"
}

View File

@ -30,7 +30,7 @@
"Inherit": "Naslijedi",
"ItemAddedWithName": "{0} je dodano u biblioteku",
"ItemRemovedWithName": "{0} je uklonjen iz biblioteke",
"LabelIpAddressValue": "Ip adresa: {0}",
"LabelIpAddressValue": "IP adresa: {0}",
"LabelRunningTimeValue": "Vrijeme rada: {0}",
"Latest": "Najnovije",
"MessageApplicationUpdated": "Jellyfin Server je ažuriran",
@ -92,5 +92,13 @@
"UserStoppedPlayingItemWithValues": "{0} je zaustavio {1}",
"ValueHasBeenAddedToLibrary": "{0} has been added to your media library",
"ValueSpecialEpisodeName": "Specijal - {0}",
"VersionNumber": "Verzija {0}"
"VersionNumber": "Verzija {0}",
"TaskRefreshLibraryDescription": "Skenira vašu medijsku knjižnicu sa novim datotekama i osvježuje metapodatke.",
"TaskRefreshLibrary": "Skeniraj medijsku knjižnicu",
"TaskRefreshChapterImagesDescription": "Stvara sličice za videozapise koji imaju poglavlja.",
"TaskRefreshChapterImages": "Raspakiraj slike poglavlja",
"TaskCleanCacheDescription": "Briše priručne datoteke nepotrebne za sistem.",
"TaskCleanCache": "Očisti priručnu memoriju",
"TasksApplicationCategory": "Aplikacija",
"TasksMaintenanceCategory": "Održavanje"
}

View File

@ -5,7 +5,7 @@
"Artists": "Artisti",
"AuthenticationSucceededWithUserName": "{0} autenticato con successo",
"Books": "Libri",
"CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera dal device {0}",
"CameraImageUploadedFrom": "È stata caricata una nuova fotografia da {0}",
"Channels": "Canali",
"ChapterNameValue": "Capitolo {0}",
"Collections": "Collezioni",

View File

@ -92,5 +92,27 @@
"UserStoppedPlayingItemWithValues": "{0} baigė leisti {1} į {2}",
"ValueHasBeenAddedToLibrary": "{0} pridėtas į mediateką",
"ValueSpecialEpisodeName": "Ypatinga - {0}",
"VersionNumber": "Version {0}"
"VersionNumber": "Version {0}",
"TaskUpdatePluginsDescription": "Atsisiųsti ir įdiegti atnaujinimus priedams kuriem yra nustatytas automatiškas atnaujinimas.",
"TaskUpdatePlugins": "Atnaujinti Priedus",
"TaskDownloadMissingSubtitlesDescription": "Ieško internete trūkstamų subtitrų remiantis metaduomenų konfigūracija.",
"TaskCleanTranscodeDescription": "Ištrina dienos senumo perkodavimo failus.",
"TaskCleanTranscode": "Išvalyti Perkodavimo Direktorija",
"TaskRefreshLibraryDescription": "Ieškoti naujų failų jūsų mediatekoje ir atnaujina metaduomenis.",
"TaskRefreshLibrary": "Skenuoti Mediateka",
"TaskDownloadMissingSubtitles": "Atsisiųsti trūkstamus subtitrus",
"TaskRefreshChannelsDescription": "Atnaujina internetinių kanalų informacija.",
"TaskRefreshChannels": "Atnaujinti Kanalus",
"TaskRefreshPeopleDescription": "Atnaujina metaduomenis apie aktorius ir režisierius jūsų mediatekoje.",
"TaskRefreshPeople": "Atnaujinti Žmones",
"TaskCleanLogsDescription": "Ištrina žurnalo failus kurie yra senesni nei {0} dienos.",
"TaskCleanLogs": "Išvalyti Žurnalą",
"TaskRefreshChapterImagesDescription": "Sukuria miniatiūras vaizdo įrašam, kurie turi scenas.",
"TaskRefreshChapterImages": "Ištraukti Scenų Paveikslus",
"TaskCleanCache": "Išvalyti Talpyklą",
"TaskCleanCacheDescription": "Ištrina talpyklos failus, kurių daugiau nereikia sistemai.",
"TasksChannelsCategory": "Internetiniai Kanalai",
"TasksApplicationCategory": "Programa",
"TasksLibraryCategory": "Mediateka",
"TasksMaintenanceCategory": "Priežiūra"
}

View File

@ -91,5 +91,12 @@
"Songs": "Песни",
"Shows": "Серии",
"ServerNameNeedsToBeRestarted": "{0} треба да се рестартира",
"ScheduledTaskStartedWithName": "{0} започна"
"ScheduledTaskStartedWithName": "{0} започна",
"TaskRefreshChapterImages": "Извези Слики од Поглавје",
"TaskCleanCacheDescription": "Ги брише кешираните фајлови што не се повеќе потребни од системот.",
"TaskCleanCache": "Исчисти Го Кешот",
"TasksChannelsCategory": "Интернет Канали",
"TasksApplicationCategory": "Апликација",
"TasksLibraryCategory": "Библиотека",
"TasksMaintenanceCategory": "Одржување"
}

View File

@ -97,5 +97,9 @@
"TasksApplicationCategory": "Applikasjon",
"TasksLibraryCategory": "Bibliotek",
"TasksMaintenanceCategory": "Vedlikehold",
"TaskCleanCache": "Tøm buffer katalog"
"TaskCleanCache": "Tøm buffer katalog",
"TaskRefreshLibrary": "Skann mediebibliotek",
"TaskRefreshChapterImagesDescription": "Lager forhåndsvisningsbilder for videoer som har kapitler.",
"TaskRefreshChapterImages": "Trekk ut Kapittelbilder",
"TaskCleanCacheDescription": "Sletter mellomlagrede filer som ikke lengre trengs av systemet."
}

View File

@ -5,7 +5,7 @@
"Artists": "Artiesten",
"AuthenticationSucceededWithUserName": "{0} is succesvol geverifieerd",
"Books": "Boeken",
"CameraImageUploadedFrom": "Er is een nieuwe afbeelding toegevoegd via {0}",
"CameraImageUploadedFrom": "Er is een nieuwe camera afbeelding toegevoegd via {0}",
"Channels": "Kanalen",
"ChapterNameValue": "Hoofdstuk {0}",
"Collections": "Verzamelingen",
@ -26,7 +26,7 @@
"HeaderLiveTV": "Live TV",
"HeaderNextUp": "Volgende",
"HeaderRecordingGroups": "Opnamegroepen",
"HomeVideos": "Start video's",
"HomeVideos": "Home video's",
"Inherit": "Overerven",
"ItemAddedWithName": "{0} is toegevoegd aan de bibliotheek",
"ItemRemovedWithName": "{0} is verwijderd uit de bibliotheek",
@ -50,7 +50,7 @@
"NotificationOptionAudioPlayback": "Muziek gestart",
"NotificationOptionAudioPlaybackStopped": "Muziek gestopt",
"NotificationOptionCameraImageUploaded": "Camera-afbeelding geüpload",
"NotificationOptionInstallationFailed": "Installatie mislukking",
"NotificationOptionInstallationFailed": "Installatie mislukt",
"NotificationOptionNewLibraryContent": "Nieuwe content toegevoegd",
"NotificationOptionPluginError": "Plug-in fout",
"NotificationOptionPluginInstalled": "Plug-in geïnstalleerd",

View File

@ -92,5 +92,26 @@
"UserStoppedPlayingItemWithValues": "{0} je nehal predvajati {1} na {2}",
"ValueHasBeenAddedToLibrary": "{0} je bil dodan vaši knjižnici",
"ValueSpecialEpisodeName": "Poseben - {0}",
"VersionNumber": "Različica {0}"
"VersionNumber": "Različica {0}",
"TaskDownloadMissingSubtitles": "Prenesi manjkajoče podnapise",
"TaskRefreshChannelsDescription": "Osveži podatke spletnih kanalov.",
"TaskRefreshChannels": "Osveži kanale",
"TaskCleanTranscodeDescription": "Izbriše več kot dan stare datoteke prekodiranja.",
"TaskCleanTranscode": "Počisti mapo prekodiranja",
"TaskUpdatePluginsDescription": "Prenese in namesti posodobitve za dodatke, ki imajo omogočene samodejne posodobitve.",
"TaskUpdatePlugins": "Posodobi dodatke",
"TaskRefreshPeopleDescription": "Osveži metapodatke za igralce in režiserje v vaši knjižnici.",
"TaskRefreshPeople": "Osveži osebe",
"TaskCleanLogsDescription": "Izbriše dnevniške datoteke starejše od {0} dni.",
"TaskCleanLogs": "Počisti mapo dnevnika",
"TaskRefreshLibraryDescription": "Preišče vašo knjižnico za nove datoteke in osveži metapodatke.",
"TaskRefreshLibrary": "Preišči knjižnico predstavnosti",
"TaskRefreshChapterImagesDescription": "Ustvari sličice za poglavja videoposnetkov.",
"TaskRefreshChapterImages": "Izvleči slike poglavij",
"TaskCleanCacheDescription": "Izbriše predpomnjene datoteke, ki niso več potrebne.",
"TaskCleanCache": "Počisti mapo predpomnilnika",
"TasksChannelsCategory": "Spletni kanali",
"TasksApplicationCategory": "Aplikacija",
"TasksLibraryCategory": "Knjižnica",
"TasksMaintenanceCategory": "Vzdrževanje"
}

View File

@ -0,0 +1,36 @@
{
"MusicVideos": "Музичні відео",
"Music": "Музика",
"Movies": "Фільми",
"MessageApplicationUpdatedTo": "Jellyfin Server був оновлений до версії {0}",
"MessageApplicationUpdated": "Jellyfin Server був оновлений",
"Latest": "Останні",
"LabelIpAddressValue": "IP-адреси: {0}",
"ItemRemovedWithName": "{0} видалено з бібліотеки",
"ItemAddedWithName": "{0} додано до бібліотеки",
"HeaderNextUp": "Наступний",
"HeaderLiveTV": "Ефірне ТБ",
"HeaderFavoriteSongs": "Улюблені пісні",
"HeaderFavoriteShows": "Улюблені шоу",
"HeaderFavoriteEpisodes": "Улюблені серії",
"HeaderFavoriteArtists": "Улюблені виконавці",
"HeaderFavoriteAlbums": "Улюблені альбоми",
"HeaderContinueWatching": "Продовжити перегляд",
"HeaderCameraUploads": "Завантажено з камери",
"HeaderAlbumArtists": "Виконавці альбомів",
"Genres": "Жанри",
"Folders": "Директорії",
"Favorites": "Улюблені",
"DeviceOnlineWithName": "{0} під'єднано",
"DeviceOfflineWithName": "{0} від'єднано",
"Collections": "Колекції",
"ChapterNameValue": "Глава {0}",
"Channels": "Канали",
"CameraImageUploadedFrom": "Нова фотографія завантажена з {0}",
"Books": "Книги",
"AuthenticationSucceededWithUserName": "{0} успішно авторизовані",
"Artists": "Виконавці",
"Application": "Додаток",
"AppDeviceValues": "Додаток: {0}, Пристрій: {1}",
"Albums": "Альбоми"
}

View File

@ -1,6 +1,6 @@
{
"Albums": "專輯",
"AppDeviceValues": "軟: {0}, 設備: {1}",
"AppDeviceValues": "軟: {0}, 設備: {1}",
"Application": "應用程式",
"Artists": "藝人",
"AuthenticationSucceededWithUserName": "{0} 授權成功",
@ -92,5 +92,8 @@
"UserStoppedPlayingItemWithValues": "{0} 已在 {2} 上停止播放 {1}",
"ValueHasBeenAddedToLibrary": "{0} 已添加到你的媒體庫",
"ValueSpecialEpisodeName": "特典 - {0}",
"VersionNumber": "版本{0}"
"VersionNumber": "版本{0}",
"TaskDownloadMissingSubtitles": "下載遺失的字幕",
"TaskUpdatePlugins": "更新插件",
"TasksApplicationCategory": "應用程式"
}

View File

@ -1,39 +0,0 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using WebSocketManager = Emby.Server.Implementations.WebSockets.WebSocketManager;
namespace Emby.Server.Implementations.Middleware
{
public class WebSocketMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<WebSocketMiddleware> _logger;
private readonly WebSocketManager _webSocketManager;
public WebSocketMiddleware(RequestDelegate next, ILogger<WebSocketMiddleware> logger, WebSocketManager webSocketManager)
{
_next = next;
_logger = logger;
_webSocketManager = webSocketManager;
}
public async Task Invoke(HttpContext httpContext)
{
_logger.LogInformation("Handling request: " + httpContext.Request.Path);
if (httpContext.WebSockets.IsWebSocketRequest)
{
var webSocketContext = await httpContext.WebSockets.AcceptWebSocketAsync(null).ConfigureAwait(false);
if (webSocketContext != null)
{
await _webSocketManager.OnWebSocketConnected(webSocketContext).ConfigureAwait(false);
}
}
else
{
await _next.Invoke(httpContext).ConfigureAwait(false);
}
}
}
}

View File

@ -1,48 +0,0 @@
using System;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
namespace Emby.Server.Implementations.Net
{
/// <summary>
/// Interface IWebSocket
/// </summary>
public interface IWebSocket : IDisposable
{
/// <summary>
/// Occurs when [closed].
/// </summary>
event EventHandler<EventArgs> Closed;
/// <summary>
/// Gets or sets the state.
/// </summary>
/// <value>The state.</value>
WebSocketState State { get; }
/// <summary>
/// Gets or sets the receive action.
/// </summary>
/// <value>The receive action.</value>
Action<byte[]> OnReceiveBytes { get; set; }
/// <summary>
/// Sends the async.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="endOfMessage">if set to <c>true</c> [end of message].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken);
/// <summary>
/// Sends the asynchronous.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="endOfMessage">if set to <c>true</c> [end of message].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken);
}
}

View File

@ -1,29 +0,0 @@
using System;
using Microsoft.AspNetCore.Http;
namespace Emby.Server.Implementations.Net
{
public class WebSocketConnectEventArgs : EventArgs
{
/// <summary>
/// Gets or sets the URL.
/// </summary>
/// <value>The URL.</value>
public string Url { get; set; }
/// <summary>
/// Gets or sets the query string.
/// </summary>
/// <value>The query string.</value>
public IQueryCollection QueryString { get; set; }
/// <summary>
/// Gets or sets the web socket.
/// </summary>
/// <value>The web socket.</value>
public IWebSocket WebSocket { get; set; }
/// <summary>
/// Gets or sets the endpoint.
/// </summary>
/// <value>The endpoint.</value>
public string Endpoint { get; set; }
}
}

View File

@ -1,191 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
namespace Emby.Server.Implementations.Session
{
public class HttpSessionController : ISessionController
{
private readonly IHttpClient _httpClient;
private readonly IJsonSerializer _json;
private readonly ISessionManager _sessionManager;
public SessionInfo Session { get; private set; }
private readonly string _postUrl;
public HttpSessionController(IHttpClient httpClient,
IJsonSerializer json,
SessionInfo session,
string postUrl, ISessionManager sessionManager)
{
_httpClient = httpClient;
_json = json;
Session = session;
_postUrl = postUrl;
_sessionManager = sessionManager;
}
private string PostUrl => string.Format("http://{0}{1}", Session.RemoteEndPoint, _postUrl);
public bool IsSessionActive => (DateTime.UtcNow - Session.LastActivityDate).TotalMinutes <= 5;
public bool SupportsMediaControl => true;
private Task SendMessage(string name, string messageId, CancellationToken cancellationToken)
{
return SendMessage(name, messageId, new Dictionary<string, string>(), cancellationToken);
}
private Task SendMessage(string name, string messageId, Dictionary<string, string> args, CancellationToken cancellationToken)
{
args["messageId"] = messageId;
var url = PostUrl + "/" + name + ToQueryString(args);
return SendRequest(new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken,
BufferContent = false
});
}
private Task SendPlayCommand(PlayRequest command, string messageId, CancellationToken cancellationToken)
{
var dict = new Dictionary<string, string>();
dict["ItemIds"] = string.Join(",", command.ItemIds.Select(i => i.ToString("N", CultureInfo.InvariantCulture)).ToArray());
if (command.StartPositionTicks.HasValue)
{
dict["StartPositionTicks"] = command.StartPositionTicks.Value.ToString(CultureInfo.InvariantCulture);
}
if (command.AudioStreamIndex.HasValue)
{
dict["AudioStreamIndex"] = command.AudioStreamIndex.Value.ToString(CultureInfo.InvariantCulture);
}
if (command.SubtitleStreamIndex.HasValue)
{
dict["SubtitleStreamIndex"] = command.SubtitleStreamIndex.Value.ToString(CultureInfo.InvariantCulture);
}
if (command.StartIndex.HasValue)
{
dict["StartIndex"] = command.StartIndex.Value.ToString(CultureInfo.InvariantCulture);
}
if (!string.IsNullOrEmpty(command.MediaSourceId))
{
dict["MediaSourceId"] = command.MediaSourceId;
}
return SendMessage(command.PlayCommand.ToString(), messageId, dict, cancellationToken);
}
private Task SendPlaystateCommand(PlaystateRequest command, string messageId, CancellationToken cancellationToken)
{
var args = new Dictionary<string, string>();
if (command.Command == PlaystateCommand.Seek)
{
if (!command.SeekPositionTicks.HasValue)
{
throw new ArgumentException("SeekPositionTicks cannot be null");
}
args["SeekPositionTicks"] = command.SeekPositionTicks.Value.ToString(CultureInfo.InvariantCulture);
}
return SendMessage(command.Command.ToString(), messageId, args, cancellationToken);
}
private string[] _supportedMessages = Array.Empty<string>();
public Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken)
{
if (!IsSessionActive)
{
return Task.CompletedTask;
}
if (string.Equals(name, "Play", StringComparison.OrdinalIgnoreCase))
{
return SendPlayCommand(data as PlayRequest, messageId, cancellationToken);
}
if (string.Equals(name, "PlayState", StringComparison.OrdinalIgnoreCase))
{
return SendPlaystateCommand(data as PlaystateRequest, messageId, cancellationToken);
}
if (string.Equals(name, "GeneralCommand", StringComparison.OrdinalIgnoreCase))
{
var command = data as GeneralCommand;
return SendMessage(command.Name, messageId, command.Arguments, cancellationToken);
}
if (!_supportedMessages.Contains(name, StringComparer.OrdinalIgnoreCase))
{
return Task.CompletedTask;
}
var url = PostUrl + "/" + name;
url += "?messageId=" + messageId;
var options = new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken,
BufferContent = false
};
if (data != null)
{
if (typeof(T) == typeof(string))
{
var str = data as string;
if (!string.IsNullOrEmpty(str))
{
options.RequestContent = str;
options.RequestContentType = "application/json";
}
}
else
{
options.RequestContent = _json.SerializeToString(data);
options.RequestContentType = "application/json";
}
}
return SendRequest(options);
}
private async Task SendRequest(HttpRequestOptions options)
{
using (var response = await _httpClient.Post(options).ConfigureAwait(false))
{
}
}
private static string ToQueryString(Dictionary<string, string> nvc)
{
var array = (from item in nvc
select string.Format("{0}={1}", WebUtility.UrlEncode(item.Key), WebUtility.UrlEncode(item.Value)))
.ToArray();
var args = string.Join("&", array);
if (string.IsNullOrEmpty(args))
{
return args;
}
return "?" + args;
}
}
}

View File

@ -477,8 +477,7 @@ namespace Emby.Server.Implementations.Session
Client = appName,
DeviceId = deviceId,
ApplicationVersion = appVersion,
Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture),
ServerId = _appHost.SystemId
Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture)
};
var username = user?.Name;
@ -1042,12 +1041,12 @@ namespace Emby.Server.Implementations.Session
private static async Task SendMessageToSession<T>(SessionInfo session, string name, T data, CancellationToken cancellationToken)
{
var controllers = session.SessionControllers.ToArray();
var messageId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
var controllers = session.SessionControllers;
var messageId = Guid.NewGuid();
foreach (var controller in controllers)
{
await controller.SendMessage(name, messageId, data, controllers, cancellationToken).ConfigureAwait(false);
await controller.SendMessage(name, messageId, data, cancellationToken).ConfigureAwait(false);
}
}
@ -1055,13 +1054,13 @@ namespace Emby.Server.Implementations.Session
{
IEnumerable<Task> GetTasks()
{
var messageId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
var messageId = Guid.NewGuid();
foreach (var session in sessions)
{
var controllers = session.SessionControllers;
foreach (var controller in controllers)
{
yield return controller.SendMessage(name, messageId, data, controllers, cancellationToken);
yield return controller.SendMessage(name, messageId, data, cancellationToken);
}
}
}
@ -1762,7 +1761,7 @@ namespace Emby.Server.Implementations.Session
throw new ArgumentNullException(nameof(info));
}
var user = info.UserId.Equals(Guid.Empty)
var user = info.UserId == Guid.Empty
? null
: _userManager.GetUserById(info.UserId);

View File

@ -3,7 +3,6 @@ using System.Threading.Tasks;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Serialization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
@ -12,7 +11,7 @@ namespace Emby.Server.Implementations.Session
/// <summary>
/// Class SessionWebSocketListener
/// </summary>
public class SessionWebSocketListener : IWebSocketListener, IDisposable
public sealed class SessionWebSocketListener : IWebSocketListener, IDisposable
{
/// <summary>
/// The _session manager
@ -23,42 +22,41 @@ namespace Emby.Server.Implementations.Session
/// The _logger
/// </summary>
private readonly ILogger _logger;
/// <summary>
/// The _dto service
/// </summary>
private readonly IJsonSerializer _json;
private readonly ILoggerFactory _loggerFactory;
private readonly IHttpServer _httpServer;
/// <summary>
/// Initializes a new instance of the <see cref="SessionWebSocketListener" /> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="sessionManager">The session manager.</param>
/// <param name="loggerFactory">The logger factory.</param>
/// <param name="json">The json.</param>
/// <param name="httpServer">The HTTP server.</param>
public SessionWebSocketListener(ISessionManager sessionManager, ILoggerFactory loggerFactory, IJsonSerializer json, IHttpServer httpServer)
public SessionWebSocketListener(
ILogger<SessionWebSocketListener> logger,
ISessionManager sessionManager,
ILoggerFactory loggerFactory,
IHttpServer httpServer)
{
_logger = logger;
_sessionManager = sessionManager;
_logger = loggerFactory.CreateLogger(GetType().Name);
_json = json;
_loggerFactory = loggerFactory;
_httpServer = httpServer;
httpServer.WebSocketConnected += _serverManager_WebSocketConnected;
httpServer.WebSocketConnected += OnServerManagerWebSocketConnected;
}
void _serverManager_WebSocketConnected(object sender, GenericEventArgs<IWebSocketConnection> e)
private void OnServerManagerWebSocketConnected(object sender, GenericEventArgs<IWebSocketConnection> e)
{
var session = GetSession(e.Argument.QueryString, e.Argument.RemoteEndPoint);
var session = GetSession(e.Argument.QueryString, e.Argument.RemoteEndPoint.ToString());
if (session != null)
{
EnsureController(session, e.Argument);
}
else
{
_logger.LogWarning("Unable to determine session based on url: {0}", e.Argument.Url);
_logger.LogWarning("Unable to determine session based on query string: {0}", e.Argument.QueryString);
}
}
@ -79,9 +77,10 @@ namespace Emby.Server.Implementations.Session
return _sessionManager.GetSessionByAuthenticationToken(token, deviceId, remoteEndpoint);
}
/// <inheritdoc />
public void Dispose()
{
_httpServer.WebSocketConnected -= _serverManager_WebSocketConnected;
_httpServer.WebSocketConnected -= OnServerManagerWebSocketConnected;
}
/// <summary>
@ -94,7 +93,8 @@ namespace Emby.Server.Implementations.Session
private void EnsureController(SessionInfo session, IWebSocketConnection connection)
{
var controllerInfo = session.EnsureController<WebSocketController>(s => new WebSocketController(s, _logger, _sessionManager));
var controllerInfo = session.EnsureController<WebSocketController>(
s => new WebSocketController(_loggerFactory.CreateLogger<WebSocketController>(), s, _sessionManager));
var controller = (WebSocketController)controllerInfo.Item1;
controller.AddWebSocket(connection);

View File

@ -1,3 +1,7 @@
#pragma warning disable CS1591
#pragma warning disable SA1600
#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,60 +15,63 @@ using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.Session
{
public class WebSocketController : ISessionController, IDisposable
public sealed class WebSocketController : ISessionController, IDisposable
{
public SessionInfo Session { get; private set; }
public IReadOnlyList<IWebSocketConnection> Sockets { get; private set; }
private readonly ILogger _logger;
private readonly ISessionManager _sessionManager;
private readonly SessionInfo _session;
public WebSocketController(SessionInfo session, ILogger logger, ISessionManager sessionManager)
private readonly List<IWebSocketConnection> _sockets;
private bool _disposed = false;
public WebSocketController(
ILogger<WebSocketController> logger,
SessionInfo session,
ISessionManager sessionManager)
{
Session = session;
_logger = logger;
_session = session;
_sessionManager = sessionManager;
Sockets = new List<IWebSocketConnection>();
_sockets = new List<IWebSocketConnection>();
}
private bool HasOpenSockets => GetActiveSockets().Any();
/// <inheritdoc />
public bool SupportsMediaControl => HasOpenSockets;
/// <inheritdoc />
public bool IsSessionActive => HasOpenSockets;
private IEnumerable<IWebSocketConnection> GetActiveSockets()
{
return Sockets
.OrderByDescending(i => i.LastActivityDate)
.Where(i => i.State == WebSocketState.Open);
}
=> _sockets.Where(i => i.State == WebSocketState.Open);
public void AddWebSocket(IWebSocketConnection connection)
{
var sockets = Sockets.ToList();
sockets.Add(connection);
_logger.LogDebug("Adding websocket to session {Session}", _session.Id);
_sockets.Add(connection);
Sockets = sockets;
connection.Closed += connection_Closed;
connection.Closed += OnConnectionClosed;
}
void connection_Closed(object sender, EventArgs e)
private void OnConnectionClosed(object sender, EventArgs e)
{
var connection = (IWebSocketConnection)sender;
var sockets = Sockets.ToList();
sockets.Remove(connection);
Sockets = sockets;
_sessionManager.CloseIfNeeded(Session);
_logger.LogDebug("Removing websocket from session {Session}", _session.Id);
_sockets.Remove(connection);
connection.Closed -= OnConnectionClosed;
_sessionManager.CloseIfNeeded(_session);
}
public Task SendMessage<T>(string name, string messageId, T data, ISessionController[] allControllers, CancellationToken cancellationToken)
/// <inheritdoc />
public Task SendMessage<T>(
string name,
Guid messageId,
T data,
CancellationToken cancellationToken)
{
var socket = GetActiveSockets()
.OrderByDescending(i => i.LastActivityDate)
.FirstOrDefault();
if (socket == null)
@ -72,21 +79,30 @@ namespace Emby.Server.Implementations.Session
return Task.CompletedTask;
}
return socket.SendAsync(new WebSocketMessage<T>
{
Data = data,
MessageType = name,
MessageId = messageId
}, cancellationToken);
return socket.SendAsync(
new WebSocketMessage<T>
{
Data = data,
MessageType = name,
MessageId = messageId
},
cancellationToken);
}
/// <inheritdoc />
public void Dispose()
{
foreach (var socket in Sockets.ToList())
if (_disposed)
{
socket.Closed -= connection_Closed;
return;
}
foreach (var socket in _sockets)
{
socket.Closed -= OnConnectionClosed;
}
_disposed = true;
}
}
}

View File

@ -1,105 +0,0 @@
using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.Net;
using Microsoft.Extensions.Logging;
namespace Emby.Server.Implementations.SocketSharp
{
public class SharpWebSocket : IWebSocket
{
/// <summary>
/// The logger
/// </summary>
private readonly ILogger _logger;
public event EventHandler<EventArgs> Closed;
/// <summary>
/// Gets or sets the web socket.
/// </summary>
/// <value>The web socket.</value>
private readonly WebSocket _webSocket;
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
private bool _disposed;
public SharpWebSocket(WebSocket socket, ILogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_webSocket = socket ?? throw new ArgumentNullException(nameof(socket));
}
/// <summary>
/// Gets the state.
/// </summary>
/// <value>The state.</value>
public WebSocketState State => _webSocket.State;
/// <summary>
/// Sends the async.
/// </summary>
/// <param name="bytes">The bytes.</param>
/// <param name="endOfMessage">if set to <c>true</c> [end of message].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public Task SendAsync(byte[] bytes, bool endOfMessage, CancellationToken cancellationToken)
{
return _webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Binary, endOfMessage, cancellationToken);
}
/// <summary>
/// Sends the asynchronous.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="endOfMessage">if set to <c>true</c> [end of message].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public Task SendAsync(string text, bool endOfMessage, CancellationToken cancellationToken)
{
return _webSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(text)), WebSocketMessageType.Text, endOfMessage, cancellationToken);
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool dispose)
{
if (_disposed)
{
return;
}
if (dispose)
{
_cancellationTokenSource.Cancel();
if (_webSocket.State == WebSocketState.Open)
{
_webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by client",
CancellationToken.None);
}
Closed?.Invoke(this, EventArgs.Empty);
}
_disposed = true;
}
/// <summary>
/// Gets or sets the receive action.
/// </summary>
/// <value>The receive action.</value>
public Action<byte[]> OnReceiveBytes { get; set; }
}
}

View File

@ -1,135 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Threading;
using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer;
using Emby.Server.Implementations.Net;
using MediaBrowser.Model.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Net.Http.Headers;
namespace Emby.Server.Implementations.SocketSharp
{
public class WebSocketSharpListener : IHttpListener
{
private readonly ILogger _logger;
private CancellationTokenSource _disposeCancellationTokenSource = new CancellationTokenSource();
private CancellationToken _disposeCancellationToken;
public WebSocketSharpListener(ILogger<WebSocketSharpListener> logger)
{
_logger = logger;
_disposeCancellationToken = _disposeCancellationTokenSource.Token;
}
public Func<Exception, IRequest, bool, bool, Task> ErrorHandler { get; set; }
public Func<IHttpRequest, string, string, string, CancellationToken, Task> RequestHandler { get; set; }
public Action<WebSocketConnectEventArgs> WebSocketConnected { get; set; }
private static void LogRequest(ILogger logger, HttpRequest request)
{
var url = request.GetDisplayUrl();
logger.LogInformation("WS {Url}. UserAgent: {UserAgent}", url, request.Headers[HeaderNames.UserAgent].ToString());
}
public async Task ProcessWebSocketRequest(HttpContext ctx)
{
try
{
LogRequest(_logger, ctx.Request);
var endpoint = ctx.Connection.RemoteIpAddress.ToString();
var url = ctx.Request.GetDisplayUrl();
var webSocketContext = await ctx.WebSockets.AcceptWebSocketAsync(null).ConfigureAwait(false);
var socket = new SharpWebSocket(webSocketContext, _logger);
WebSocketConnected(new WebSocketConnectEventArgs
{
Url = url,
QueryString = ctx.Request.Query,
WebSocket = socket,
Endpoint = endpoint
});
WebSocketReceiveResult result;
var message = new List<byte>();
do
{
var buffer = WebSocket.CreateServerBuffer(4096);
result = await webSocketContext.ReceiveAsync(buffer, _disposeCancellationToken);
message.AddRange(buffer.Array.Take(result.Count));
if (result.EndOfMessage)
{
socket.OnReceiveBytes(message.ToArray());
message.Clear();
}
} while (socket.State == WebSocketState.Open && result.MessageType != WebSocketMessageType.Close);
if (webSocketContext.State == WebSocketState.Open)
{
await webSocketContext.CloseAsync(
result.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
result.CloseStatusDescription,
_disposeCancellationToken).ConfigureAwait(false);
}
socket.Dispose();
}
catch (Exception ex)
{
_logger.LogError(ex, "AcceptWebSocketAsync error");
if (!ctx.Response.HasStarted)
{
ctx.Response.StatusCode = 500;
}
}
}
public Task Stop()
{
_disposeCancellationTokenSource.Cancel();
return Task.CompletedTask;
}
/// <summary>
/// Releases the unmanaged resources and disposes of the managed resources used.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool _disposed;
/// <summary>
/// Releases the unmanaged resources and disposes of the managed resources used.
/// </summary>
/// <param name="disposing">Whether or not the managed resources should be disposed.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
Stop().GetAwaiter().GetResult();
}
_disposed = true;
}
}
}

View File

@ -63,6 +63,9 @@ namespace Emby.Server.Implementations.SocketSharp
if (!IPAddress.TryParse(GetHeader(CustomHeaderNames.XRealIP), out ip))
{
ip = Request.HttpContext.Connection.RemoteIpAddress;
// Default to the loopback address if no RemoteIpAddress is specified (i.e. during integration tests)
ip ??= IPAddress.Loopback;
}
}
@ -90,7 +93,10 @@ namespace Emby.Server.Implementations.SocketSharp
public IQueryCollection QueryString => Request.Query;
public bool IsLocal => Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress);
public bool IsLocal =>
(Request.HttpContext.Connection.LocalIpAddress == null
&& Request.HttpContext.Connection.RemoteIpAddress == null)
|| Request.HttpContext.Connection.LocalIpAddress.Equals(Request.HttpContext.Connection.RemoteIpAddress);
public string HttpMethod => Request.Method;

View File

@ -1,10 +0,0 @@
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
namespace Emby.Server.Implementations.WebSockets
{
public interface IWebSocketHandler
{
Task ProcessMessage(WebSocketMessage<object> message, TaskCompletionSource<bool> taskCompletionSource);
}
}

View File

@ -1,102 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging;
using UtfUnknown;
namespace Emby.Server.Implementations.WebSockets
{
public class WebSocketManager
{
private readonly IWebSocketHandler[] _webSocketHandlers;
private readonly IJsonSerializer _jsonSerializer;
private readonly ILogger<WebSocketManager> _logger;
private const int BufferSize = 4096;
public WebSocketManager(IWebSocketHandler[] webSocketHandlers, IJsonSerializer jsonSerializer, ILogger<WebSocketManager> logger)
{
_webSocketHandlers = webSocketHandlers;
_jsonSerializer = jsonSerializer;
_logger = logger;
}
public async Task OnWebSocketConnected(WebSocket webSocket)
{
var taskCompletionSource = new TaskCompletionSource<bool>();
var cancellationToken = new CancellationTokenSource().Token;
WebSocketReceiveResult result;
var message = new List<byte>();
// Keep listening for incoming messages, otherwise the socket closes automatically
do
{
var buffer = WebSocket.CreateServerBuffer(BufferSize);
result = await webSocket.ReceiveAsync(buffer, cancellationToken).ConfigureAwait(false);
message.AddRange(buffer.Array.Take(result.Count));
if (result.EndOfMessage)
{
await ProcessMessage(message.ToArray(), taskCompletionSource).ConfigureAwait(false);
message.Clear();
}
} while (!taskCompletionSource.Task.IsCompleted &&
webSocket.State == WebSocketState.Open &&
result.MessageType != WebSocketMessageType.Close);
if (webSocket.State == WebSocketState.Open)
{
await webSocket.CloseAsync(
result.CloseStatus ?? WebSocketCloseStatus.NormalClosure,
result.CloseStatusDescription,
cancellationToken).ConfigureAwait(false);
}
}
private async Task ProcessMessage(byte[] messageBytes, TaskCompletionSource<bool> taskCompletionSource)
{
var charset = CharsetDetector.DetectFromBytes(messageBytes).Detected?.EncodingName;
var message = string.Equals(charset, "utf-8", StringComparison.OrdinalIgnoreCase)
? Encoding.UTF8.GetString(messageBytes, 0, messageBytes.Length)
: Encoding.ASCII.GetString(messageBytes, 0, messageBytes.Length);
// All messages are expected to be valid JSON objects
if (!message.StartsWith("{", StringComparison.OrdinalIgnoreCase))
{
_logger.LogDebug("Received web socket message that is not a json structure: {Message}", message);
return;
}
try
{
var info = _jsonSerializer.DeserializeFromString<WebSocketMessage<object>>(message);
_logger.LogDebug("Websocket message received: {0}", info.MessageType);
var tasks = _webSocketHandlers.Select(handler => Task.Run(() =>
{
try
{
handler.ProcessMessage(info, taskCompletionSource).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(ex, "{HandlerType} failed processing WebSocket message {MessageType}",
handler.GetType().Name, info.MessageType ?? string.Empty);
}
}));
await Task.WhenAll(tasks);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error processing web socket message");
}
}
}
}

View File

@ -1,3 +1,4 @@
using System.Security.Authentication;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
@ -59,6 +60,10 @@ namespace Jellyfin.Api.Auth
return Task.FromResult(AuthenticateResult.Success(ticket));
}
catch (AuthenticationException ex)
{
return Task.FromResult(AuthenticateResult.Fail(ex));
}
catch (SecurityException ex)
{
return Task.FromResult(AuthenticateResult.Fail(ex));

View File

@ -13,7 +13,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="3.1.4" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.0.0" />
</ItemGroup>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.Extensions.Logging;
namespace Jellyfin.Data.Entities
{
/// <summary>
/// An entity referencing an activity log entry.
/// </summary>
public partial class ActivityLog : ISavingChanges
{
/// <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)
{
if (string.IsNullOrEmpty(name))
{
throw new ArgumentNullException(nameof(name));
}
if (string.IsNullOrEmpty(type))
{
throw new ArgumentNullException(nameof(type));
}
this.Name = name;
this.Type = type;
this.UserId = userId;
this.DateCreated = DateTime.UtcNow;
this.LogSeverity = LogLevel.Trace;
Init();
}
/// <summary>
/// Initializes a new instance of the <see cref="ActivityLog"/> class.
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected ActivityLog()
{
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name">The name.</param>
/// <param name="type">The type.</param>
/// <param name="userId">The user's id.</param>
/// <returns>The new <see cref="ActivityLog"/> instance.</returns>
public static ActivityLog Create(string name, string type, Guid userId)
{
return new ActivityLog(name, type, userId);
}
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Gets or sets the identity of this instance.
/// This is the key in the backing database.
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; protected set; }
/// <summary>
/// Gets or sets the name.
/// Required, Max length = 512.
/// </summary>
[Required]
[MaxLength(512)]
[StringLength(512)]
public string Name { get; set; }
/// <summary>
/// Gets or sets the overview.
/// Max length = 512.
/// </summary>
[MaxLength(512)]
[StringLength(512)]
public string Overview { get; set; }
/// <summary>
/// Gets or sets the short overview.
/// Max length = 512.
/// </summary>
[MaxLength(512)]
[StringLength(512)]
public string ShortOverview { get; set; }
/// <summary>
/// Gets or sets the type.
/// Required, Max length = 256.
/// </summary>
[Required]
[MaxLength(256)]
[StringLength(256)]
public string Type { get; set; }
/// <summary>
/// Gets or sets the user id.
/// Required.
/// </summary>
[Required]
public Guid UserId { get; set; }
/// <summary>
/// Gets or sets the item id.
/// Max length = 256.
/// </summary>
[MaxLength(256)]
[StringLength(256)]
public string ItemId { get; set; }
/// <summary>
/// Gets or sets the date created. This should be in UTC.
/// Required.
/// </summary>
[Required]
public DateTime DateCreated { get; set; }
/// <summary>
/// Gets or sets the log severity. Default is <see cref="LogLevel.Trace"/>.
/// Required.
/// </summary>
[Required]
public LogLevel LogSeverity { get; set; }
/// <summary>
/// Gets or sets the row version.
/// Required, ConcurrencyToken.
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
partial void Init();
/// <inheritdoc />
public void OnSavingChanges()
{
RowVersion++;
}
}
}

View File

@ -1,208 +1,195 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Artwork
{
partial void Init();
public partial class Artwork
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Artwork()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Artwork()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Artwork CreateArtworkUnsafe()
{
return new Artwork();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Artwork CreateArtworkUnsafe()
{
return new Artwork();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path"></param>
/// <param name="kind"></param>
/// <param name="_metadata0"></param>
/// <param name="_personrole1"></param>
public Artwork(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path"></param>
/// <param name="kind"></param>
/// <param name="_metadata0"></param>
/// <param name="_personrole1"></param>
public Artwork(string path, Enums.ArtKind kind, Metadata _metadata0, PersonRole _personrole1)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
this.Kind = kind;
this.Kind = kind;
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Artwork.Add(this);
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Artwork.Add(this);
if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1));
_personrole1.Artwork = this;
if (_personrole1 == null) throw new ArgumentNullException(nameof(_personrole1));
_personrole1.Artwork = this;
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path"></param>
/// <param name="kind"></param>
/// <param name="_metadata0"></param>
/// <param name="_personrole1"></param>
public static Artwork Create(string path, global::Jellyfin.Data.Enums.ArtKind kind, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.PersonRole _personrole1)
{
return new Artwork(path, kind, _metadata0, _personrole1);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path"></param>
/// <param name="kind"></param>
/// <param name="_metadata0"></param>
/// <param name="_personrole1"></param>
public static Artwork Create(string path, Enums.ArtKind kind, Metadata _metadata0, PersonRole _personrole1)
{
return new Artwork(path, kind, _metadata0, _personrole1);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Required, Max length = 65535
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
protected set
{
_Path = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Backing field for Kind
/// </summary>
internal global::Jellyfin.Data.Enums.ArtKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(global::Jellyfin.Data.Enums.ArtKind oldValue, ref global::Jellyfin.Data.Enums.ArtKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref global::Jellyfin.Data.Enums.ArtKind result);
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Indexed, Required
/// </summary>
[Required]
public global::Jellyfin.Data.Enums.ArtKind Kind
{
get
{
global::Jellyfin.Data.Enums.ArtKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
global::Jellyfin.Data.Enums.ArtKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Required, Max length = 65535
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
_Kind = value;
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
}
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
{
_Path = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for Kind
/// </summary>
internal Enums.ArtKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(Enums.ArtKind oldValue, ref Enums.ArtKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref Enums.ArtKind result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Indexed, Required
/// </summary>
[Required]
public Enums.ArtKind Kind
{
get
{
Enums.ArtKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
Enums.ArtKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
{
_Kind = value;
}
}
}
}
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,84 +1,69 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Book: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
public partial class Book : LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Book(): base()
{
BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>();
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Book()
{
BookMetadata = new HashSet<BookMetadata>();
Releases = new HashSet<Release>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Book CreateBookUnsafe()
{
return new Book();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Book CreateBookUnsafe()
{
return new Book();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public Book(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public Book(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.BookMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.BookMetadata>();
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
this.BookMetadata = new HashSet<BookMetadata>();
this.Releases = new HashSet<Release>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static Book Create(Guid urlid, DateTime dateadded)
{
return new Book(urlid, dateadded);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static Book Create(Guid urlid, DateTime dateadded)
{
return new Book(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.BookMetadata> BookMetadata { get; protected set; }
[ForeignKey("BookMetadata_BookMetadata_Id")]
public virtual ICollection<BookMetadata> BookMetadata { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
[ForeignKey("Release_Releases_Id")]
public virtual ICollection<Release> Releases { get; protected set; }
}
}
}

View File

@ -1,123 +1,107 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class BookMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
public partial class BookMetadata : Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected BookMetadata(): base()
{
Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected BookMetadata()
{
Publishers = new HashSet<Company>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static BookMetadata CreateBookMetadataUnsafe()
{
return new BookMetadata();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static BookMetadata CreateBookMetadataUnsafe()
{
return new BookMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_book0"></param>
public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_book0"></param>
public BookMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_book0 == null) throw new ArgumentNullException(nameof(_book0));
_book0.BookMetadata.Add(this);
if (_book0 == null) throw new ArgumentNullException(nameof(_book0));
_book0.BookMetadata.Add(this);
this.Publishers = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
this.Publishers = new HashSet<Company>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_book0"></param>
public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Book _book0)
{
return new BookMetadata(title, language, dateadded, datemodified, _book0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_book0"></param>
public static BookMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Book _book0)
{
return new BookMetadata(title, language, dateadded, datemodified, _book0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for ISBN
/// </summary>
protected long? _ISBN;
/// <summary>
/// When provided in a partial class, allows value of ISBN to be changed before setting.
/// </summary>
partial void SetISBN(long? oldValue, ref long? newValue);
/// <summary>
/// When provided in a partial class, allows value of ISBN to be changed before returning.
/// </summary>
partial void GetISBN(ref long? result);
/// <summary>
/// Backing field for ISBN
/// </summary>
protected long? _ISBN;
/// <summary>
/// When provided in a partial class, allows value of ISBN to be changed before setting.
/// </summary>
partial void SetISBN(long? oldValue, ref long? newValue);
/// <summary>
/// When provided in a partial class, allows value of ISBN to be changed before returning.
/// </summary>
partial void GetISBN(ref long? result);
public long? ISBN
{
get
{
long? value = _ISBN;
GetISBN(ref value);
return (_ISBN = value);
}
set
{
long? oldValue = _ISBN;
SetISBN(oldValue, ref value);
if (oldValue != value)
public long? ISBN
{
get
{
_ISBN = value;
long? value = _ISBN;
GetISBN(ref value);
return (_ISBN = value);
}
}
}
set
{
long? oldValue = _ISBN;
SetISBN(oldValue, ref value);
if (oldValue != value)
{
_ISBN = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Company> Publishers { get; protected set; }
[ForeignKey("Company_Publishers_Id")]
public virtual ICollection<Company> Publishers { get; protected set; }
}
}
}

View File

@ -1,274 +1,263 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Chapter
{
partial void Init();
public partial class Chapter
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Chapter()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Chapter()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Chapter CreateChapterUnsafe()
{
return new Chapter();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Chapter CreateChapterUnsafe()
{
return new Chapter();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="timestart"></param>
/// <param name="_release0"></param>
public Chapter(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0)
{
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="timestart"></param>
/// <param name="_release0"></param>
public Chapter(string language, long timestart, Release _release0)
{
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
this.TimeStart = timestart;
this.TimeStart = timestart;
if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
_release0.Chapters.Add(this);
if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
_release0.Chapters.Add(this);
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="timestart"></param>
/// <param name="_release0"></param>
public static Chapter Create(string language, long timestart, global::Jellyfin.Data.Entities.Release _release0)
{
return new Chapter(language, timestart, _release0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="timestart"></param>
/// <param name="_release0"></param>
public static Chapter Create(string language, long timestart, Release _release0)
{
return new Chapter(language, timestart, _release0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
protected set
{
_Name = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Backing field for Language
/// </summary>
protected string _Language;
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before setting.
/// </summary>
partial void SetLanguage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before returning.
/// </summary>
partial void GetLanguage(ref string result);
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Required, Min length = 3, Max length = 3
/// ISO-639-3 3-character language codes
/// </summary>
[Required]
[MinLength(3)]
[MaxLength(3)]
[StringLength(3)]
public string Language
{
get
{
string value = _Language;
GetLanguage(ref value);
return (_Language = value);
}
set
{
string oldValue = _Language;
SetLanguage(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
_Language = value;
string value = _Name;
GetName(ref value);
return (_Name = value);
}
}
}
/// <summary>
/// Backing field for TimeStart
/// </summary>
protected long _TimeStart;
/// <summary>
/// When provided in a partial class, allows value of TimeStart to be changed before setting.
/// </summary>
partial void SetTimeStart(long oldValue, ref long newValue);
/// <summary>
/// When provided in a partial class, allows value of TimeStart to be changed before returning.
/// </summary>
partial void GetTimeStart(ref long result);
/// <summary>
/// Required
/// </summary>
[Required]
public long TimeStart
{
get
{
long value = _TimeStart;
GetTimeStart(ref value);
return (_TimeStart = value);
}
set
{
long oldValue = _TimeStart;
SetTimeStart(oldValue, ref value);
if (oldValue != value)
set
{
_TimeStart = value;
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
}
}
/// <summary>
/// Backing field for TimeEnd
/// </summary>
protected long? _TimeEnd;
/// <summary>
/// When provided in a partial class, allows value of TimeEnd to be changed before setting.
/// </summary>
partial void SetTimeEnd(long? oldValue, ref long? newValue);
/// <summary>
/// When provided in a partial class, allows value of TimeEnd to be changed before returning.
/// </summary>
partial void GetTimeEnd(ref long? result);
/// <summary>
/// Backing field for Language
/// </summary>
protected string _Language;
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before setting.
/// </summary>
partial void SetLanguage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before returning.
/// </summary>
partial void GetLanguage(ref string result);
public long? TimeEnd
{
get
{
long? value = _TimeEnd;
GetTimeEnd(ref value);
return (_TimeEnd = value);
}
set
{
long? oldValue = _TimeEnd;
SetTimeEnd(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Required, Min length = 3, Max length = 3
/// ISO-639-3 3-character language codes
/// </summary>
[Required]
[MinLength(3)]
[MaxLength(3)]
[StringLength(3)]
public string Language
{
get
{
_TimeEnd = value;
string value = _Language;
GetLanguage(ref value);
return (_Language = value);
}
}
}
set
{
string oldValue = _Language;
SetLanguage(oldValue, ref value);
if (oldValue != value)
{
_Language = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for TimeStart
/// </summary>
protected long _TimeStart;
/// <summary>
/// When provided in a partial class, allows value of TimeStart to be changed before setting.
/// </summary>
partial void SetTimeStart(long oldValue, ref long newValue);
/// <summary>
/// When provided in a partial class, allows value of TimeStart to be changed before returning.
/// </summary>
partial void GetTimeStart(ref long result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
[Required]
public long TimeStart
{
get
{
long value = _TimeStart;
GetTimeStart(ref value);
return (_TimeStart = value);
}
set
{
long oldValue = _TimeStart;
SetTimeStart(oldValue, ref value);
if (oldValue != value)
{
_TimeStart = value;
}
}
}
}
/// <summary>
/// Backing field for TimeEnd
/// </summary>
protected long? _TimeEnd;
/// <summary>
/// When provided in a partial class, allows value of TimeEnd to be changed before setting.
/// </summary>
partial void SetTimeEnd(long? oldValue, ref long? newValue);
/// <summary>
/// When provided in a partial class, allows value of TimeEnd to be changed before returning.
/// </summary>
partial void GetTimeEnd(ref long? result);
public long? TimeEnd
{
get
{
long? value = _TimeEnd;
GetTimeEnd(ref value);
return (_TimeEnd = value);
}
set
{
long? oldValue = _TimeEnd;
SetTimeEnd(oldValue, ref value);
if (oldValue != value)
{
_TimeEnd = value;
}
}
}
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,131 +1,120 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Collection
{
partial void Init();
public partial class Collection
{
partial void Init();
/// <summary>
/// Default constructor
/// </summary>
public Collection()
{
CollectionItem = new System.Collections.Generic.LinkedList<global::Jellyfin.Data.Entities.CollectionItem>();
/// <summary>
/// Default constructor
/// </summary>
public Collection()
{
CollectionItem = new LinkedList<CollectionItem>();
Init();
}
Init();
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
protected set
{
_Name = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
public virtual ICollection<global::Jellyfin.Data.Entities.CollectionItem> CollectionItem { get; protected set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
}
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("CollectionItem_CollectionItem_Id")]
public virtual ICollection<CollectionItem> CollectionItem { get; protected set; }
}
}

View File

@ -1,151 +1,143 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CollectionItem
{
partial void Init();
public partial class CollectionItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CollectionItem()
{
// NOTE: This class has one-to-one associations with CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CollectionItem()
{
// NOTE: This class has one-to-one associations with CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CollectionItem CreateCollectionItemUnsafe()
{
return new CollectionItem();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CollectionItem CreateCollectionItemUnsafe()
{
return new CollectionItem();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="_collection0"></param>
/// <param name="_collectionitem1"></param>
/// <param name="_collectionitem2"></param>
public CollectionItem(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2)
{
// NOTE: This class has one-to-one associations with CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="_collection0"></param>
/// <param name="_collectionitem1"></param>
/// <param name="_collectionitem2"></param>
public CollectionItem(Collection _collection0, CollectionItem _collectionitem1, CollectionItem _collectionitem2)
{
// NOTE: This class has one-to-one associations with CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0));
_collection0.CollectionItem.Add(this);
if (_collection0 == null) throw new ArgumentNullException(nameof(_collection0));
_collection0.CollectionItem.Add(this);
if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1));
_collectionitem1.Next = this;
if (_collectionitem1 == null) throw new ArgumentNullException(nameof(_collectionitem1));
_collectionitem1.Next = this;
if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2));
_collectionitem2.Previous = this;
if (_collectionitem2 == null) throw new ArgumentNullException(nameof(_collectionitem2));
_collectionitem2.Previous = this;
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="_collection0"></param>
/// <param name="_collectionitem1"></param>
/// <param name="_collectionitem2"></param>
public static CollectionItem Create(global::Jellyfin.Data.Entities.Collection _collection0, global::Jellyfin.Data.Entities.CollectionItem _collectionitem1, global::Jellyfin.Data.Entities.CollectionItem _collectionitem2)
{
return new CollectionItem(_collection0, _collectionitem1, _collectionitem2);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="_collection0"></param>
/// <param name="_collectionitem1"></param>
/// <param name="_collectionitem2"></param>
public static CollectionItem Create(Collection _collection0, CollectionItem _collectionitem1, CollectionItem _collectionitem2)
{
return new CollectionItem(_collection0, _collectionitem1, _collectionitem2);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public void OnSavingChanges()
{
RowVersion++;
}
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.LibraryItem LibraryItem { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <remarks>
/// TODO check if this properly updated dependant and has the proper principal relationship
/// </remarks>
public virtual global::Jellyfin.Data.Entities.CollectionItem Next { get; set; }
/// <summary>
/// Required
/// </summary>
[ForeignKey("LibraryItem_Id")]
public virtual LibraryItem LibraryItem { get; set; }
/// <remarks>
/// TODO check if this properly updated dependant and has the proper principal relationship
/// </remarks>
public virtual global::Jellyfin.Data.Entities.CollectionItem Previous { get; set; }
/// <remarks>
/// TODO check if this properly updated dependant and has the proper principal relationship
/// </remarks>
[ForeignKey("CollectionItem_Next_Id")]
public virtual CollectionItem Next { get; set; }
}
/// <remarks>
/// TODO check if this properly updated dependant and has the proper principal relationship
/// </remarks>
[ForeignKey("CollectionItem_Previous_Id")]
public virtual CollectionItem Previous { get; set; }
}
}

View File

@ -1,147 +1,137 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Company
{
partial void Init();
public partial class Company
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Company()
{
CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Company()
{
CompanyMetadata = new HashSet<CompanyMetadata>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Company CreateCompanyUnsafe()
{
return new Company();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Company CreateCompanyUnsafe()
{
return new Company();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="_moviemetadata0"></param>
/// <param name="_seriesmetadata1"></param>
/// <param name="_musicalbummetadata2"></param>
/// <param name="_bookmetadata3"></param>
/// <param name="_company4"></param>
public Company(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4)
{
if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0));
_moviemetadata0.Studios.Add(this);
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="_moviemetadata0"></param>
/// <param name="_seriesmetadata1"></param>
/// <param name="_musicalbummetadata2"></param>
/// <param name="_bookmetadata3"></param>
/// <param name="_company4"></param>
public Company(MovieMetadata _moviemetadata0, SeriesMetadata _seriesmetadata1, MusicAlbumMetadata _musicalbummetadata2, BookMetadata _bookmetadata3, Company _company4)
{
if (_moviemetadata0 == null) throw new ArgumentNullException(nameof(_moviemetadata0));
_moviemetadata0.Studios.Add(this);
if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1));
_seriesmetadata1.Networks.Add(this);
if (_seriesmetadata1 == null) throw new ArgumentNullException(nameof(_seriesmetadata1));
_seriesmetadata1.Networks.Add(this);
if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2));
_musicalbummetadata2.Labels.Add(this);
if (_musicalbummetadata2 == null) throw new ArgumentNullException(nameof(_musicalbummetadata2));
_musicalbummetadata2.Labels.Add(this);
if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3));
_bookmetadata3.Publishers.Add(this);
if (_bookmetadata3 == null) throw new ArgumentNullException(nameof(_bookmetadata3));
_bookmetadata3.Publishers.Add(this);
if (_company4 == null) throw new ArgumentNullException(nameof(_company4));
_company4.Parent = this;
if (_company4 == null) throw new ArgumentNullException(nameof(_company4));
_company4.Parent = this;
this.CompanyMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CompanyMetadata>();
this.CompanyMetadata = new HashSet<CompanyMetadata>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="_moviemetadata0"></param>
/// <param name="_seriesmetadata1"></param>
/// <param name="_musicalbummetadata2"></param>
/// <param name="_bookmetadata3"></param>
/// <param name="_company4"></param>
public static Company Create(global::Jellyfin.Data.Entities.MovieMetadata _moviemetadata0, global::Jellyfin.Data.Entities.SeriesMetadata _seriesmetadata1, global::Jellyfin.Data.Entities.MusicAlbumMetadata _musicalbummetadata2, global::Jellyfin.Data.Entities.BookMetadata _bookmetadata3, global::Jellyfin.Data.Entities.Company _company4)
{
return new Company(_moviemetadata0, _seriesmetadata1, _musicalbummetadata2, _bookmetadata3, _company4);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="_moviemetadata0"></param>
/// <param name="_seriesmetadata1"></param>
/// <param name="_musicalbummetadata2"></param>
/// <param name="_bookmetadata3"></param>
/// <param name="_company4"></param>
public static Company Create(MovieMetadata _moviemetadata0, SeriesMetadata _seriesmetadata1, MusicAlbumMetadata _musicalbummetadata2, BookMetadata _bookmetadata3, Company _company4)
{
return new Company(_moviemetadata0, _seriesmetadata1, _musicalbummetadata2, _bookmetadata3, _company4);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public void OnSavingChanges()
{
RowVersion++;
}
public virtual ICollection<global::Jellyfin.Data.Entities.CompanyMetadata> CompanyMetadata { get; protected set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("CompanyMetadata_CompanyMetadata_Id")]
public virtual ICollection<CompanyMetadata> CompanyMetadata { get; protected set; }
[ForeignKey("Company_Parent_Id")]
public virtual Company Parent { get; set; }
public virtual global::Jellyfin.Data.Entities.Company Parent { get; set; }
}
}
}

View File

@ -1,234 +1,216 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CompanyMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
public partial class CompanyMetadata : Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CompanyMetadata(): base()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CompanyMetadata()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CompanyMetadata CreateCompanyMetadataUnsafe()
{
return new CompanyMetadata();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CompanyMetadata CreateCompanyMetadataUnsafe()
{
return new CompanyMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_company0"></param>
public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_company0"></param>
public CompanyMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_company0 == null) throw new ArgumentNullException(nameof(_company0));
_company0.CompanyMetadata.Add(this);
if (_company0 == null) throw new ArgumentNullException(nameof(_company0));
_company0.CompanyMetadata.Add(this);
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_company0"></param>
public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Company _company0)
{
return new CompanyMetadata(title, language, dateadded, datemodified, _company0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_company0"></param>
public static CompanyMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Company _company0)
{
return new CompanyMetadata(title, language, dateadded, datemodified, _company0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Description
/// </summary>
protected string _Description;
/// <summary>
/// When provided in a partial class, allows value of Description to be changed before setting.
/// </summary>
partial void SetDescription(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Description to be changed before returning.
/// </summary>
partial void GetDescription(ref string result);
/// <summary>
/// Backing field for Description
/// </summary>
protected string _Description;
/// <summary>
/// When provided in a partial class, allows value of Description to be changed before setting.
/// </summary>
partial void SetDescription(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Description to be changed before returning.
/// </summary>
partial void GetDescription(ref string result);
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Description
{
get
{
string value = _Description;
GetDescription(ref value);
return (_Description = value);
}
set
{
string oldValue = _Description;
SetDescription(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Description
{
get
{
_Description = value;
string value = _Description;
GetDescription(ref value);
return (_Description = value);
}
}
}
/// <summary>
/// Backing field for Headquarters
/// </summary>
protected string _Headquarters;
/// <summary>
/// When provided in a partial class, allows value of Headquarters to be changed before setting.
/// </summary>
partial void SetHeadquarters(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Headquarters to be changed before returning.
/// </summary>
partial void GetHeadquarters(ref string result);
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string Headquarters
{
get
{
string value = _Headquarters;
GetHeadquarters(ref value);
return (_Headquarters = value);
}
set
{
string oldValue = _Headquarters;
SetHeadquarters(oldValue, ref value);
if (oldValue != value)
set
{
_Headquarters = value;
string oldValue = _Description;
SetDescription(oldValue, ref value);
if (oldValue != value)
{
_Description = value;
}
}
}
}
}
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
/// <summary>
/// Backing field for Headquarters
/// </summary>
protected string _Headquarters;
/// <summary>
/// When provided in a partial class, allows value of Headquarters to be changed before setting.
/// </summary>
partial void SetHeadquarters(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Headquarters to be changed before returning.
/// </summary>
partial void GetHeadquarters(ref string result);
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string Headquarters
{
get
{
_Country = value;
string value = _Headquarters;
GetHeadquarters(ref value);
return (_Headquarters = value);
}
}
}
/// <summary>
/// Backing field for Homepage
/// </summary>
protected string _Homepage;
/// <summary>
/// When provided in a partial class, allows value of Homepage to be changed before setting.
/// </summary>
partial void SetHomepage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Homepage to be changed before returning.
/// </summary>
partial void GetHomepage(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Homepage
{
get
{
string value = _Homepage;
GetHomepage(ref value);
return (_Homepage = value);
}
set
{
string oldValue = _Homepage;
SetHomepage(oldValue, ref value);
if (oldValue != value)
set
{
_Homepage = value;
string oldValue = _Headquarters;
SetHeadquarters(oldValue, ref value);
if (oldValue != value)
{
_Headquarters = value;
}
}
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
}
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
{
_Country = value;
}
}
}
/// <summary>
/// Backing field for Homepage
/// </summary>
protected string _Homepage;
/// <summary>
/// When provided in a partial class, allows value of Homepage to be changed before setting.
/// </summary>
partial void SetHomepage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Homepage to be changed before returning.
/// </summary>
partial void GetHomepage(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Homepage
{
get
{
string value = _Homepage;
GetHomepage(ref value);
return (_Homepage = value);
}
set
{
string oldValue = _Homepage;
SetHomepage(oldValue, ref value);
if (oldValue != value)
{
_Homepage = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,84 +1,68 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CustomItem: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
public partial class CustomItem : LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CustomItem(): base()
{
CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>();
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CustomItem()
{
CustomItemMetadata = new HashSet<CustomItemMetadata>();
Releases = new HashSet<Release>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CustomItem CreateCustomItemUnsafe()
{
return new CustomItem();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CustomItem CreateCustomItemUnsafe()
{
return new CustomItem();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public CustomItem(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public CustomItem(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.CustomItemMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.CustomItemMetadata>();
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
this.CustomItemMetadata = new HashSet<CustomItemMetadata>();
this.Releases = new HashSet<Release>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static CustomItem Create(Guid urlid, DateTime dateadded)
{
return new CustomItem(urlid, dateadded);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static CustomItem Create(Guid urlid, DateTime dateadded)
{
return new CustomItem(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("CustomItemMetadata_CustomItemMetadata_Id")]
public virtual ICollection<CustomItemMetadata> CustomItemMetadata { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.CustomItemMetadata> CustomItemMetadata { get; protected set; }
[ForeignKey("Release_Releases_Id")]
public virtual ICollection<Release> Releases { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
}
}
}

View File

@ -1,86 +1,67 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class CustomItemMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
public partial class CustomItemMetadata : Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CustomItemMetadata(): base()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected CustomItemMetadata()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CustomItemMetadata CreateCustomItemMetadataUnsafe()
{
return new CustomItemMetadata();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static CustomItemMetadata CreateCustomItemMetadataUnsafe()
{
return new CustomItemMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_customitem0"></param>
public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_customitem0"></param>
public CustomItemMetadata(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0));
_customitem0.CustomItemMetadata.Add(this);
if (_customitem0 == null) throw new ArgumentNullException(nameof(_customitem0));
_customitem0.CustomItemMetadata.Add(this);
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_customitem0"></param>
public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.CustomItem _customitem0)
{
return new CustomItemMetadata(title, language, dateadded, datemodified, _customitem0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_customitem0"></param>
public static CustomItemMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, CustomItem _customitem0)
{
return new CustomItemMetadata(title, language, dateadded, datemodified, _customitem0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}
}

View File

@ -1,127 +1,110 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Episode: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
public partial class Episode : LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Episode(): base()
{
// NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Episode()
{
// NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>();
Releases = new HashSet<Release>();
EpisodeMetadata = new HashSet<EpisodeMetadata>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Episode CreateEpisodeUnsafe()
{
return new Episode();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Episode CreateEpisodeUnsafe()
{
return new Episode();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
/// <param name="_season0"></param>
public Episode(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0)
{
// NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
/// <param name="_season0"></param>
public Episode(Guid urlid, DateTime dateadded, Season _season0)
{
// NOTE: This class has one-to-one associations with LibraryRoot, LibraryItem and CollectionItem.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
this.UrlId = urlid;
this.UrlId = urlid;
if (_season0 == null) throw new ArgumentNullException(nameof(_season0));
_season0.Episodes.Add(this);
if (_season0 == null) throw new ArgumentNullException(nameof(_season0));
_season0.Episodes.Add(this);
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
this.EpisodeMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.EpisodeMetadata>();
this.Releases = new HashSet<Release>();
this.EpisodeMetadata = new HashSet<EpisodeMetadata>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
/// <param name="_season0"></param>
public static Episode Create(Guid urlid, DateTime dateadded, global::Jellyfin.Data.Entities.Season _season0)
{
return new Episode(urlid, dateadded, _season0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
/// <param name="_season0"></param>
public static Episode Create(Guid urlid, DateTime dateadded, Season _season0)
{
return new Episode(urlid, dateadded, _season0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for EpisodeNumber
/// </summary>
protected int? _EpisodeNumber;
/// <summary>
/// When provided in a partial class, allows value of EpisodeNumber to be changed before setting.
/// </summary>
partial void SetEpisodeNumber(int? oldValue, ref int? newValue);
/// <summary>
/// When provided in a partial class, allows value of EpisodeNumber to be changed before returning.
/// </summary>
partial void GetEpisodeNumber(ref int? result);
/// <summary>
/// Backing field for EpisodeNumber
/// </summary>
protected int? _EpisodeNumber;
/// <summary>
/// When provided in a partial class, allows value of EpisodeNumber to be changed before setting.
/// </summary>
partial void SetEpisodeNumber(int? oldValue, ref int? newValue);
/// <summary>
/// When provided in a partial class, allows value of EpisodeNumber to be changed before returning.
/// </summary>
partial void GetEpisodeNumber(ref int? result);
public int? EpisodeNumber
{
get
{
int? value = _EpisodeNumber;
GetEpisodeNumber(ref value);
return (_EpisodeNumber = value);
}
set
{
int? oldValue = _EpisodeNumber;
SetEpisodeNumber(oldValue, ref value);
if (oldValue != value)
public int? EpisodeNumber
{
get
{
_EpisodeNumber = value;
int? value = _EpisodeNumber;
GetEpisodeNumber(ref value);
return (_EpisodeNumber = value);
}
}
}
set
{
int? oldValue = _EpisodeNumber;
SetEpisodeNumber(oldValue, ref value);
if (oldValue != value)
{
_EpisodeNumber = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("Release_Releases_Id")]
public virtual ICollection<Release> Releases { get; protected set; }
[ForeignKey("EpisodeMetadata_EpisodeMetadata_Id")]
public virtual ICollection<EpisodeMetadata> EpisodeMetadata { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.EpisodeMetadata> EpisodeMetadata { get; protected set; }
}
}
}

View File

@ -1,197 +1,179 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class EpisodeMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
public partial class EpisodeMetadata : Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected EpisodeMetadata(): base()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected EpisodeMetadata()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static EpisodeMetadata CreateEpisodeMetadataUnsafe()
{
return new EpisodeMetadata();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static EpisodeMetadata CreateEpisodeMetadataUnsafe()
{
return new EpisodeMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_episode0"></param>
public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_episode0"></param>
public EpisodeMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0));
_episode0.EpisodeMetadata.Add(this);
if (_episode0 == null) throw new ArgumentNullException(nameof(_episode0));
_episode0.EpisodeMetadata.Add(this);
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_episode0"></param>
public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Episode _episode0)
{
return new EpisodeMetadata(title, language, dateadded, datemodified, _episode0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_episode0"></param>
public static EpisodeMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Episode _episode0)
{
return new EpisodeMetadata(title, language, dateadded, datemodified, _episode0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Outline
/// </summary>
protected string _Outline;
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before setting.
/// </summary>
partial void SetOutline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before returning.
/// </summary>
partial void GetOutline(ref string result);
/// <summary>
/// Backing field for Outline
/// </summary>
protected string _Outline;
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before setting.
/// </summary>
partial void SetOutline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before returning.
/// </summary>
partial void GetOutline(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Outline
{
get
{
string value = _Outline;
GetOutline(ref value);
return (_Outline = value);
}
set
{
string oldValue = _Outline;
SetOutline(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Outline
{
get
{
_Outline = value;
string value = _Outline;
GetOutline(ref value);
return (_Outline = value);
}
}
}
/// <summary>
/// Backing field for Plot
/// </summary>
protected string _Plot;
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before setting.
/// </summary>
partial void SetPlot(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before returning.
/// </summary>
partial void GetPlot(ref string result);
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Plot
{
get
{
string value = _Plot;
GetPlot(ref value);
return (_Plot = value);
}
set
{
string oldValue = _Plot;
SetPlot(oldValue, ref value);
if (oldValue != value)
set
{
_Plot = value;
string oldValue = _Outline;
SetOutline(oldValue, ref value);
if (oldValue != value)
{
_Outline = value;
}
}
}
}
}
/// <summary>
/// Backing field for Tagline
/// </summary>
protected string _Tagline;
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before setting.
/// </summary>
partial void SetTagline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before returning.
/// </summary>
partial void GetTagline(ref string result);
/// <summary>
/// Backing field for Plot
/// </summary>
protected string _Plot;
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before setting.
/// </summary>
partial void SetPlot(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before returning.
/// </summary>
partial void GetPlot(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Tagline
{
get
{
string value = _Tagline;
GetTagline(ref value);
return (_Tagline = value);
}
set
{
string oldValue = _Tagline;
SetTagline(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Plot
{
get
{
_Tagline = value;
string value = _Plot;
GetPlot(ref value);
return (_Plot = value);
}
}
}
set
{
string oldValue = _Plot;
SetPlot(oldValue, ref value);
if (oldValue != value)
{
_Plot = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Backing field for Tagline
/// </summary>
protected string _Tagline;
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before setting.
/// </summary>
partial void SetTagline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before returning.
/// </summary>
partial void GetTagline(ref string result);
}
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Tagline
{
get
{
string value = _Tagline;
GetTagline(ref value);
return (_Tagline = value);
}
set
{
string oldValue = _Tagline;
SetTagline(oldValue, ref value);
if (oldValue != value)
{
_Tagline = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,163 +1,152 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Genre
{
partial void Init();
public partial class Genre
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Genre()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Genre()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Genre CreateGenreUnsafe()
{
return new Genre();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Genre CreateGenreUnsafe()
{
return new Genre();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
/// <param name="_metadata0"></param>
public Genre(string name, global::Jellyfin.Data.Entities.Metadata _metadata0)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
/// <param name="_metadata0"></param>
public Genre(string name, Metadata _metadata0)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Genres.Add(this);
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Genres.Add(this);
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
/// <param name="_metadata0"></param>
public static Genre Create(string name, global::Jellyfin.Data.Entities.Metadata _metadata0)
{
return new Genre(name, _metadata0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
/// <param name="_metadata0"></param>
public static Genre Create(string name, Metadata _metadata0)
{
return new Genre(name, _metadata0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
internal string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Indexed, Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
protected set
{
_Name = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for Name
/// </summary>
internal string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Indexed, Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
}
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,115 +1,109 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Group
{
partial void Init();
public partial class Group
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Group()
{
GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Group()
{
GroupPermissions = new HashSet<Permission>();
ProviderMappings = new HashSet<ProviderMapping>();
Preferences = new HashSet<Preference>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Group CreateGroupUnsafe()
{
return new Group();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Group CreateGroupUnsafe()
{
return new Group();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
/// <param name="_user0"></param>
public Group(string name, global::Jellyfin.Data.Entities.User _user0)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
/// <param name="_user0"></param>
public Group(string name, User _user0)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
_user0.Groups.Add(this);
if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
_user0.Groups.Add(this);
this.GroupPermissions = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Permission>();
this.ProviderMappings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.ProviderMapping>();
this.Preferences = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Preference>();
this.GroupPermissions = new HashSet<Permission>();
this.ProviderMappings = new HashSet<ProviderMapping>();
this.Preferences = new HashSet<Preference>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
/// <param name="_user0"></param>
public static Group Create(string name, global::Jellyfin.Data.Entities.User _user0)
{
return new Group(name, _user0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
/// <param name="_user0"></param>
public static Group Create(string name, User _user0)
{
return new Group(name, _user0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id { get; protected set; }
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; protected set; }
/// <summary>
/// Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Name { get; set; }
/// <summary>
/// Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string Name { get; set; }
/// <summary>
/// Concurrency token
/// </summary>
[Timestamp]
public Byte[] Timestamp { get; set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public void OnSavingChanges()
{
RowVersion++;
}
public virtual ICollection<global::Jellyfin.Data.Entities.Permission> GroupPermissions { get; protected set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.ProviderMapping> ProviderMappings { get; protected set; }
[ForeignKey("Permission_GroupPermissions_Id")]
public virtual ICollection<Permission> GroupPermissions { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Preference> Preferences { get; protected set; }
[ForeignKey("ProviderMapping_ProviderMappings_Id")]
public virtual ICollection<ProviderMapping> ProviderMappings { get; protected set; }
}
[ForeignKey("Preference_Preferences_Id")]
public virtual ICollection<Preference> Preferences { get; protected set; }
}
}

View File

@ -1,158 +1,147 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Library
{
partial void Init();
public partial class Library
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Library()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Library()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Library CreateLibraryUnsafe()
{
return new Library();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Library CreateLibraryUnsafe()
{
return new Library();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
public Library(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
public Library(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
public static Library Create(string name)
{
return new Library(name);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
public static Library Create(string name)
{
return new Library(name);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Required, Max length = 1024
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
protected set
{
_Name = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required, Max length = 1024
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
}
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,180 +1,170 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public abstract partial class LibraryItem
{
partial void Init();
public abstract partial class LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to being abstract.
/// </summary>
protected LibraryItem()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to being abstract.
/// </summary>
protected LibraryItem()
{
Init();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
protected LibraryItem(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
protected LibraryItem(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
Init();
}
Init();
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for UrlId
/// </summary>
internal Guid _UrlId;
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before setting.
/// </summary>
partial void SetUrlId(Guid oldValue, ref Guid newValue);
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before returning.
/// </summary>
partial void GetUrlId(ref Guid result);
/// <summary>
/// Indexed, Required
/// This is whats gets displayed in the Urls and API requests. This could also be a string.
/// </summary>
[Required]
public Guid UrlId
{
get
{
Guid value = _UrlId;
GetUrlId(ref value);
return (_UrlId = value);
}
set
{
Guid oldValue = _UrlId;
SetUrlId(oldValue, ref value);
if (oldValue != value)
protected set
{
_UrlId = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Backing field for DateAdded
/// </summary>
protected DateTime _DateAdded;
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before setting.
/// </summary>
partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before returning.
/// </summary>
partial void GetDateAdded(ref DateTime result);
/// <summary>
/// Backing field for UrlId
/// </summary>
internal Guid _UrlId;
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before setting.
/// </summary>
partial void SetUrlId(Guid oldValue, ref Guid newValue);
/// <summary>
/// When provided in a partial class, allows value of UrlId to be changed before returning.
/// </summary>
partial void GetUrlId(ref Guid result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateAdded
{
get
{
DateTime value = _DateAdded;
GetDateAdded(ref value);
return (_DateAdded = value);
}
internal set
{
DateTime oldValue = _DateAdded;
SetDateAdded(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Indexed, Required
/// This is whats gets displayed in the Urls and API requests. This could also be a string.
/// </summary>
[Required]
public Guid UrlId
{
get
{
_DateAdded = value;
Guid value = _UrlId;
GetUrlId(ref value);
return (_UrlId = value);
}
}
}
set
{
Guid oldValue = _UrlId;
SetUrlId(oldValue, ref value);
if (oldValue != value)
{
_UrlId = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for DateAdded
/// </summary>
protected DateTime _DateAdded;
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before setting.
/// </summary>
partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before returning.
/// </summary>
partial void GetDateAdded(ref DateTime result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateAdded
{
get
{
DateTime value = _DateAdded;
GetDateAdded(ref value);
return (_DateAdded = value);
}
internal set
{
DateTime oldValue = _DateAdded;
SetDateAdded(oldValue, ref value);
if (oldValue != value)
{
_DateAdded = value;
}
}
}
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.LibraryRoot LibraryRoot { get; set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
}
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
[ForeignKey("LibraryRoot_Id")]
public virtual LibraryRoot LibraryRoot { get; set; }
}
}

View File

@ -1,202 +1,192 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class LibraryRoot
{
partial void Init();
public partial class LibraryRoot
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected LibraryRoot()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected LibraryRoot()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static LibraryRoot CreateLibraryRootUnsafe()
{
return new LibraryRoot();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static LibraryRoot CreateLibraryRootUnsafe()
{
return new LibraryRoot();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path">Absolute Path</param>
public LibraryRoot(string path)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path">Absolute Path</param>
public LibraryRoot(string path)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path">Absolute Path</param>
public static LibraryRoot Create(string path)
{
return new LibraryRoot(path);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path">Absolute Path</param>
public static LibraryRoot Create(string path)
{
return new LibraryRoot(path);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Required, Max length = 65535
/// Absolute Path
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
protected set
{
_Path = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Backing field for NetworkPath
/// </summary>
protected string _NetworkPath;
/// <summary>
/// When provided in a partial class, allows value of NetworkPath to be changed before setting.
/// </summary>
partial void SetNetworkPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of NetworkPath to be changed before returning.
/// </summary>
partial void GetNetworkPath(ref string result);
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Max length = 65535
/// Absolute network path, for example for transcoding sattelites.
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string NetworkPath
{
get
{
string value = _NetworkPath;
GetNetworkPath(ref value);
return (_NetworkPath = value);
}
set
{
string oldValue = _NetworkPath;
SetNetworkPath(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Required, Max length = 65535
/// Absolute Path
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
_NetworkPath = value;
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
}
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
{
_Path = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for NetworkPath
/// </summary>
protected string _NetworkPath;
/// <summary>
/// When provided in a partial class, allows value of NetworkPath to be changed before setting.
/// </summary>
partial void SetNetworkPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of NetworkPath to be changed before returning.
/// </summary>
partial void GetNetworkPath(ref string result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Max length = 65535
/// Absolute network path, for example for transcoding sattelites.
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string NetworkPath
{
get
{
string value = _NetworkPath;
GetNetworkPath(ref value);
return (_NetworkPath = value);
}
set
{
string oldValue = _NetworkPath;
SetNetworkPath(oldValue, ref value);
if (oldValue != value)
{
_NetworkPath = value;
}
}
}
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.Library Library { get; set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
}
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
[ForeignKey("Library_Id")]
public virtual Library Library { get; set; }
}
}

View File

@ -1,209 +1,200 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MediaFile
{
partial void Init();
public partial class MediaFile
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MediaFile()
{
MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MediaFile()
{
MediaFileStreams = new HashSet<MediaFileStream>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MediaFile CreateMediaFileUnsafe()
{
return new MediaFile();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MediaFile CreateMediaFileUnsafe()
{
return new MediaFile();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path">Relative to the LibraryRoot</param>
/// <param name="kind"></param>
/// <param name="_release0"></param>
public MediaFile(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="path">Relative to the LibraryRoot</param>
/// <param name="kind"></param>
/// <param name="_release0"></param>
public MediaFile(string path, Enums.MediaFileKind kind, Release _release0)
{
if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path));
this.Path = path;
this.Kind = kind;
this.Kind = kind;
if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
_release0.MediaFiles.Add(this);
if (_release0 == null) throw new ArgumentNullException(nameof(_release0));
_release0.MediaFiles.Add(this);
this.MediaFileStreams = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MediaFileStream>();
this.MediaFileStreams = new HashSet<MediaFileStream>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path">Relative to the LibraryRoot</param>
/// <param name="kind"></param>
/// <param name="_release0"></param>
public static MediaFile Create(string path, global::Jellyfin.Data.Enums.MediaFileKind kind, global::Jellyfin.Data.Entities.Release _release0)
{
return new MediaFile(path, kind, _release0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="path">Relative to the LibraryRoot</param>
/// <param name="kind"></param>
/// <param name="_release0"></param>
public static MediaFile Create(string path, Enums.MediaFileKind kind, Release _release0)
{
return new MediaFile(path, kind, _release0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Required, Max length = 65535
/// Relative to the LibraryRoot
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
protected set
{
_Path = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Backing field for Kind
/// </summary>
protected global::Jellyfin.Data.Enums.MediaFileKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(global::Jellyfin.Data.Enums.MediaFileKind oldValue, ref global::Jellyfin.Data.Enums.MediaFileKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref global::Jellyfin.Data.Enums.MediaFileKind result);
/// <summary>
/// Backing field for Path
/// </summary>
protected string _Path;
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before setting.
/// </summary>
partial void SetPath(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Path to be changed before returning.
/// </summary>
partial void GetPath(ref string result);
/// <summary>
/// Required
/// </summary>
[Required]
public global::Jellyfin.Data.Enums.MediaFileKind Kind
{
get
{
global::Jellyfin.Data.Enums.MediaFileKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
global::Jellyfin.Data.Enums.MediaFileKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Required, Max length = 65535
/// Relative to the LibraryRoot
/// </summary>
[Required]
[MaxLength(65535)]
[StringLength(65535)]
public string Path
{
get
{
_Kind = value;
string value = _Path;
GetPath(ref value);
return (_Path = value);
}
}
}
set
{
string oldValue = _Path;
SetPath(oldValue, ref value);
if (oldValue != value)
{
_Path = value;
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for Kind
/// </summary>
protected Enums.MediaFileKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(Enums.MediaFileKind oldValue, ref Enums.MediaFileKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref Enums.MediaFileKind result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
[Required]
public Enums.MediaFileKind Kind
{
get
{
Enums.MediaFileKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
Enums.MediaFileKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
{
_Kind = value;
}
}
}
public virtual ICollection<global::Jellyfin.Data.Entities.MediaFileStream> MediaFileStreams { get; protected set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
}
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("MediaFileStream_MediaFileStreams_Id")]
public virtual ICollection<MediaFileStream> MediaFileStreams { get; protected set; }
}
}

View File

@ -1,160 +1,149 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MediaFileStream
{
partial void Init();
public partial class MediaFileStream
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MediaFileStream()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MediaFileStream()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MediaFileStream CreateMediaFileStreamUnsafe()
{
return new MediaFileStream();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MediaFileStream CreateMediaFileStreamUnsafe()
{
return new MediaFileStream();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="streamnumber"></param>
/// <param name="_mediafile0"></param>
public MediaFileStream(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0)
{
this.StreamNumber = streamnumber;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="streamnumber"></param>
/// <param name="_mediafile0"></param>
public MediaFileStream(int streamnumber, MediaFile _mediafile0)
{
this.StreamNumber = streamnumber;
if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0));
_mediafile0.MediaFileStreams.Add(this);
if (_mediafile0 == null) throw new ArgumentNullException(nameof(_mediafile0));
_mediafile0.MediaFileStreams.Add(this);
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="streamnumber"></param>
/// <param name="_mediafile0"></param>
public static MediaFileStream Create(int streamnumber, global::Jellyfin.Data.Entities.MediaFile _mediafile0)
{
return new MediaFileStream(streamnumber, _mediafile0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="streamnumber"></param>
/// <param name="_mediafile0"></param>
public static MediaFileStream Create(int streamnumber, MediaFile _mediafile0)
{
return new MediaFileStream(streamnumber, _mediafile0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for StreamNumber
/// </summary>
protected int _StreamNumber;
/// <summary>
/// When provided in a partial class, allows value of StreamNumber to be changed before setting.
/// </summary>
partial void SetStreamNumber(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of StreamNumber to be changed before returning.
/// </summary>
partial void GetStreamNumber(ref int result);
/// <summary>
/// Required
/// </summary>
[Required]
public int StreamNumber
{
get
{
int value = _StreamNumber;
GetStreamNumber(ref value);
return (_StreamNumber = value);
}
set
{
int oldValue = _StreamNumber;
SetStreamNumber(oldValue, ref value);
if (oldValue != value)
protected set
{
_StreamNumber = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for StreamNumber
/// </summary>
protected int _StreamNumber;
/// <summary>
/// When provided in a partial class, allows value of StreamNumber to be changed before setting.
/// </summary>
partial void SetStreamNumber(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of StreamNumber to be changed before returning.
/// </summary>
partial void GetStreamNumber(ref int result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
[Required]
public int StreamNumber
{
get
{
int value = _StreamNumber;
GetStreamNumber(ref value);
return (_StreamNumber = value);
}
set
{
int oldValue = _StreamNumber;
SetStreamNumber(oldValue, ref value);
if (oldValue != value)
{
_StreamNumber = value;
}
}
}
}
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,385 +1,380 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public abstract partial class Metadata
{
partial void Init();
public abstract partial class Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to being abstract.
/// </summary>
protected Metadata()
{
PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>();
Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>();
Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>();
Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>();
Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
/// <summary>
/// Default constructor. Protected due to being abstract.
/// </summary>
protected Metadata()
{
PersonRoles = new HashSet<PersonRole>();
Genres = new HashSet<Genre>();
Artwork = new HashSet<Artwork>();
Ratings = new HashSet<Rating>();
Sources = new HashSet<MetadataProviderId>();
Init();
}
Init();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
protected Metadata(string title, string language, DateTime dateadded, DateTime datemodified)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
this.PersonRoles = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.PersonRole>();
this.Genres = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Genre>();
this.Artwork = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Artwork>();
this.Ratings = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Rating>();
this.Sources = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MetadataProviderId>();
this.PersonRoles = new HashSet<PersonRole>();
this.Genres = new HashSet<Genre>();
this.Artwork = new HashSet<Artwork>();
this.Ratings = new HashSet<Rating>();
this.Sources = new HashSet<MetadataProviderId>();
Init();
}
Init();
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Title
/// </summary>
protected string _Title;
/// <summary>
/// When provided in a partial class, allows value of Title to be changed before setting.
/// </summary>
partial void SetTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Title to be changed before returning.
/// </summary>
partial void GetTitle(ref string result);
/// <summary>
/// Required, Max length = 1024
/// The title or name of the object
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Title
{
get
{
string value = _Title;
GetTitle(ref value);
return (_Title = value);
}
set
{
string oldValue = _Title;
SetTitle(oldValue, ref value);
if (oldValue != value)
protected set
{
_Title = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Backing field for OriginalTitle
/// </summary>
protected string _OriginalTitle;
/// <summary>
/// When provided in a partial class, allows value of OriginalTitle to be changed before setting.
/// </summary>
partial void SetOriginalTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of OriginalTitle to be changed before returning.
/// </summary>
partial void GetOriginalTitle(ref string result);
/// <summary>
/// Backing field for Title
/// </summary>
protected string _Title;
/// <summary>
/// When provided in a partial class, allows value of Title to be changed before setting.
/// </summary>
partial void SetTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Title to be changed before returning.
/// </summary>
partial void GetTitle(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string OriginalTitle
{
get
{
string value = _OriginalTitle;
GetOriginalTitle(ref value);
return (_OriginalTitle = value);
}
set
{
string oldValue = _OriginalTitle;
SetOriginalTitle(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Required, Max length = 1024
/// The title or name of the object
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Title
{
get
{
_OriginalTitle = value;
string value = _Title;
GetTitle(ref value);
return (_Title = value);
}
}
}
/// <summary>
/// Backing field for SortTitle
/// </summary>
protected string _SortTitle;
/// <summary>
/// When provided in a partial class, allows value of SortTitle to be changed before setting.
/// </summary>
partial void SetSortTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of SortTitle to be changed before returning.
/// </summary>
partial void GetSortTitle(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string SortTitle
{
get
{
string value = _SortTitle;
GetSortTitle(ref value);
return (_SortTitle = value);
}
set
{
string oldValue = _SortTitle;
SetSortTitle(oldValue, ref value);
if (oldValue != value)
set
{
_SortTitle = value;
string oldValue = _Title;
SetTitle(oldValue, ref value);
if (oldValue != value)
{
_Title = value;
}
}
}
}
}
/// <summary>
/// Backing field for Language
/// </summary>
protected string _Language;
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before setting.
/// </summary>
partial void SetLanguage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before returning.
/// </summary>
partial void GetLanguage(ref string result);
/// <summary>
/// Backing field for OriginalTitle
/// </summary>
protected string _OriginalTitle;
/// <summary>
/// When provided in a partial class, allows value of OriginalTitle to be changed before setting.
/// </summary>
partial void SetOriginalTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of OriginalTitle to be changed before returning.
/// </summary>
partial void GetOriginalTitle(ref string result);
/// <summary>
/// Required, Min length = 3, Max length = 3
/// ISO-639-3 3-character language codes
/// </summary>
[Required]
[MinLength(3)]
[MaxLength(3)]
[StringLength(3)]
public string Language
{
get
{
string value = _Language;
GetLanguage(ref value);
return (_Language = value);
}
set
{
string oldValue = _Language;
SetLanguage(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string OriginalTitle
{
get
{
_Language = value;
string value = _OriginalTitle;
GetOriginalTitle(ref value);
return (_OriginalTitle = value);
}
}
}
/// <summary>
/// Backing field for ReleaseDate
/// </summary>
protected DateTimeOffset? _ReleaseDate;
/// <summary>
/// When provided in a partial class, allows value of ReleaseDate to be changed before setting.
/// </summary>
partial void SetReleaseDate(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
/// <summary>
/// When provided in a partial class, allows value of ReleaseDate to be changed before returning.
/// </summary>
partial void GetReleaseDate(ref DateTimeOffset? result);
public DateTimeOffset? ReleaseDate
{
get
{
DateTimeOffset? value = _ReleaseDate;
GetReleaseDate(ref value);
return (_ReleaseDate = value);
}
set
{
DateTimeOffset? oldValue = _ReleaseDate;
SetReleaseDate(oldValue, ref value);
if (oldValue != value)
set
{
_ReleaseDate = value;
string oldValue = _OriginalTitle;
SetOriginalTitle(oldValue, ref value);
if (oldValue != value)
{
_OriginalTitle = value;
}
}
}
}
}
/// <summary>
/// Backing field for DateAdded
/// </summary>
protected DateTime _DateAdded;
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before setting.
/// </summary>
partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before returning.
/// </summary>
partial void GetDateAdded(ref DateTime result);
/// <summary>
/// Backing field for SortTitle
/// </summary>
protected string _SortTitle;
/// <summary>
/// When provided in a partial class, allows value of SortTitle to be changed before setting.
/// </summary>
partial void SetSortTitle(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of SortTitle to be changed before returning.
/// </summary>
partial void GetSortTitle(ref string result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateAdded
{
get
{
DateTime value = _DateAdded;
GetDateAdded(ref value);
return (_DateAdded = value);
}
internal set
{
DateTime oldValue = _DateAdded;
SetDateAdded(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string SortTitle
{
get
{
_DateAdded = value;
string value = _SortTitle;
GetSortTitle(ref value);
return (_SortTitle = value);
}
}
}
/// <summary>
/// Backing field for DateModified
/// </summary>
protected DateTime _DateModified;
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before setting.
/// </summary>
partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before returning.
/// </summary>
partial void GetDateModified(ref DateTime result);
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateModified
{
get
{
DateTime value = _DateModified;
GetDateModified(ref value);
return (_DateModified = value);
}
internal set
{
DateTime oldValue = _DateModified;
SetDateModified(oldValue, ref value);
if (oldValue != value)
set
{
_DateModified = value;
string oldValue = _SortTitle;
SetSortTitle(oldValue, ref value);
if (oldValue != value)
{
_SortTitle = value;
}
}
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for Language
/// </summary>
protected string _Language;
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before setting.
/// </summary>
partial void SetLanguage(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Language to be changed before returning.
/// </summary>
partial void GetLanguage(ref string result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required, Min length = 3, Max length = 3
/// ISO-639-3 3-character language codes
/// </summary>
[Required]
[MinLength(3)]
[MaxLength(3)]
[StringLength(3)]
public string Language
{
get
{
string value = _Language;
GetLanguage(ref value);
return (_Language = value);
}
set
{
string oldValue = _Language;
SetLanguage(oldValue, ref value);
if (oldValue != value)
{
_Language = value;
}
}
}
public virtual ICollection<global::Jellyfin.Data.Entities.PersonRole> PersonRoles { get; protected set; }
/// <summary>
/// Backing field for ReleaseDate
/// </summary>
protected DateTimeOffset? _ReleaseDate;
/// <summary>
/// When provided in a partial class, allows value of ReleaseDate to be changed before setting.
/// </summary>
partial void SetReleaseDate(DateTimeOffset? oldValue, ref DateTimeOffset? newValue);
/// <summary>
/// When provided in a partial class, allows value of ReleaseDate to be changed before returning.
/// </summary>
partial void GetReleaseDate(ref DateTimeOffset? result);
public virtual ICollection<global::Jellyfin.Data.Entities.Genre> Genres { get; protected set; }
public DateTimeOffset? ReleaseDate
{
get
{
DateTimeOffset? value = _ReleaseDate;
GetReleaseDate(ref value);
return (_ReleaseDate = value);
}
set
{
DateTimeOffset? oldValue = _ReleaseDate;
SetReleaseDate(oldValue, ref value);
if (oldValue != value)
{
_ReleaseDate = value;
}
}
}
public virtual ICollection<global::Jellyfin.Data.Entities.Artwork> Artwork { get; protected set; }
/// <summary>
/// Backing field for DateAdded
/// </summary>
protected DateTime _DateAdded;
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before setting.
/// </summary>
partial void SetDateAdded(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateAdded to be changed before returning.
/// </summary>
partial void GetDateAdded(ref DateTime result);
public virtual ICollection<global::Jellyfin.Data.Entities.Rating> Ratings { get; protected set; }
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateAdded
{
get
{
DateTime value = _DateAdded;
GetDateAdded(ref value);
return (_DateAdded = value);
}
internal set
{
DateTime oldValue = _DateAdded;
SetDateAdded(oldValue, ref value);
if (oldValue != value)
{
_DateAdded = value;
}
}
}
public virtual ICollection<global::Jellyfin.Data.Entities.MetadataProviderId> Sources { get; protected set; }
/// <summary>
/// Backing field for DateModified
/// </summary>
protected DateTime _DateModified;
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before setting.
/// </summary>
partial void SetDateModified(DateTime oldValue, ref DateTime newValue);
/// <summary>
/// When provided in a partial class, allows value of DateModified to be changed before returning.
/// </summary>
partial void GetDateModified(ref DateTime result);
}
/// <summary>
/// Required
/// </summary>
[Required]
public DateTime DateModified
{
get
{
DateTime value = _DateModified;
GetDateModified(ref value);
return (_DateModified = value);
}
internal set
{
DateTime oldValue = _DateModified;
SetDateModified(oldValue, ref value);
if (oldValue != value)
{
_DateModified = value;
}
}
}
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("PersonRole_PersonRoles_Id")]
public virtual ICollection<PersonRole> PersonRoles { get; protected set; }
[ForeignKey("PersonRole_PersonRoles_Id")]
public virtual ICollection<Genre> Genres { get; protected set; }
[ForeignKey("PersonRole_PersonRoles_Id")]
public virtual ICollection<Artwork> Artwork { get; protected set; }
[ForeignKey("PersonRole_PersonRoles_Id")]
public virtual ICollection<Rating> Ratings { get; protected set; }
[ForeignKey("PersonRole_PersonRoles_Id")]
public virtual ICollection<MetadataProviderId> Sources { get; protected set; }
}
}

View File

@ -1,158 +1,147 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MetadataProvider
{
partial void Init();
public partial class MetadataProvider
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MetadataProvider()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MetadataProvider()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MetadataProvider CreateMetadataProviderUnsafe()
{
return new MetadataProvider();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MetadataProvider CreateMetadataProviderUnsafe()
{
return new MetadataProvider();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
public MetadataProvider(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="name"></param>
public MetadataProvider(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
this.Name = name;
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
public static MetadataProvider Create(string name)
{
return new MetadataProvider(name);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="name"></param>
public static MetadataProvider Create(string name)
{
return new MetadataProvider(name);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/// <summary>
/// Required, Max length = 1024
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
protected set
{
_Name = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for Name
/// </summary>
protected string _Name;
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before setting.
/// </summary>
partial void SetName(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Name to be changed before returning.
/// </summary>
partial void GetName(ref string result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required, Max length = 1024
/// </summary>
[Required]
[MaxLength(1024)]
[StringLength(1024)]
public string Name
{
get
{
string value = _Name;
GetName(ref value);
return (_Name = value);
}
set
{
string oldValue = _Name;
SetName(oldValue, ref value);
if (oldValue != value)
{
_Name = value;
}
}
}
}
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
}
}

View File

@ -1,189 +1,179 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MetadataProviderId
{
partial void Init();
public partial class MetadataProviderId
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MetadataProviderId()
{
// NOTE: This class has one-to-one associations with MetadataProviderId.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MetadataProviderId()
{
// NOTE: This class has one-to-one associations with MetadataProviderId.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MetadataProviderId CreateMetadataProviderIdUnsafe()
{
return new MetadataProviderId();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MetadataProviderId CreateMetadataProviderIdUnsafe()
{
return new MetadataProviderId();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="providerid"></param>
/// <param name="_metadata0"></param>
/// <param name="_person1"></param>
/// <param name="_personrole2"></param>
/// <param name="_ratingsource3"></param>
public MetadataProviderId(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3)
{
// NOTE: This class has one-to-one associations with MetadataProviderId.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="providerid"></param>
/// <param name="_metadata0"></param>
/// <param name="_person1"></param>
/// <param name="_personrole2"></param>
/// <param name="_ratingsource3"></param>
public MetadataProviderId(string providerid, Metadata _metadata0, Person _person1, PersonRole _personrole2, RatingSource _ratingsource3)
{
// NOTE: This class has one-to-one associations with MetadataProviderId.
// One-to-one associations are not validated in constructors since this causes a scenario where each one must be constructed before the other.
if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid));
this.ProviderId = providerid;
if (string.IsNullOrEmpty(providerid)) throw new ArgumentNullException(nameof(providerid));
this.ProviderId = providerid;
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Sources.Add(this);
if (_metadata0 == null) throw new ArgumentNullException(nameof(_metadata0));
_metadata0.Sources.Add(this);
if (_person1 == null) throw new ArgumentNullException(nameof(_person1));
_person1.Sources.Add(this);
if (_person1 == null) throw new ArgumentNullException(nameof(_person1));
_person1.Sources.Add(this);
if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2));
_personrole2.Sources.Add(this);
if (_personrole2 == null) throw new ArgumentNullException(nameof(_personrole2));
_personrole2.Sources.Add(this);
if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3));
_ratingsource3.Source = this;
if (_ratingsource3 == null) throw new ArgumentNullException(nameof(_ratingsource3));
_ratingsource3.Source = this;
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="providerid"></param>
/// <param name="_metadata0"></param>
/// <param name="_person1"></param>
/// <param name="_personrole2"></param>
/// <param name="_ratingsource3"></param>
public static MetadataProviderId Create(string providerid, global::Jellyfin.Data.Entities.Metadata _metadata0, global::Jellyfin.Data.Entities.Person _person1, global::Jellyfin.Data.Entities.PersonRole _personrole2, global::Jellyfin.Data.Entities.RatingSource _ratingsource3)
{
return new MetadataProviderId(providerid, _metadata0, _person1, _personrole2, _ratingsource3);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="providerid"></param>
/// <param name="_metadata0"></param>
/// <param name="_person1"></param>
/// <param name="_personrole2"></param>
/// <param name="_ratingsource3"></param>
public static MetadataProviderId Create(string providerid, Metadata _metadata0, Person _person1, PersonRole _personrole2, RatingSource _ratingsource3)
{
return new MetadataProviderId(providerid, _metadata0, _person1, _personrole2, _ratingsource3);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Backing field for Id
/// </summary>
internal int _Id;
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before setting.
/// </summary>
partial void SetId(int oldValue, ref int newValue);
/// <summary>
/// When provided in a partial class, allows value of Id to be changed before returning.
/// </summary>
partial void GetId(ref int result);
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id
{
get
{
int value = _Id;
GetId(ref value);
return (_Id = value);
}
protected set
{
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id
{
get
{
_Id = value;
int value = _Id;
GetId(ref value);
return (_Id = value);
}
}
}
/// <summary>
/// Backing field for ProviderId
/// </summary>
protected string _ProviderId;
/// <summary>
/// When provided in a partial class, allows value of ProviderId to be changed before setting.
/// </summary>
partial void SetProviderId(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of ProviderId to be changed before returning.
/// </summary>
partial void GetProviderId(ref string result);
/// <summary>
/// Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string ProviderId
{
get
{
string value = _ProviderId;
GetProviderId(ref value);
return (_ProviderId = value);
}
set
{
string oldValue = _ProviderId;
SetProviderId(oldValue, ref value);
if (oldValue != value)
protected set
{
_ProviderId = value;
int oldValue = _Id;
SetId(oldValue, ref value);
if (oldValue != value)
{
_Id = value;
}
}
}
}
}
/// <summary>
/// Required
/// </summary>
[ConcurrencyCheck]
[Required]
public byte[] Timestamp { get; set; }
/// <summary>
/// Backing field for ProviderId
/// </summary>
protected string _ProviderId;
/// <summary>
/// When provided in a partial class, allows value of ProviderId to be changed before setting.
/// </summary>
partial void SetProviderId(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of ProviderId to be changed before returning.
/// </summary>
partial void GetProviderId(ref string result);
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required, Max length = 255
/// </summary>
[Required]
[MaxLength(255)]
[StringLength(255)]
public string ProviderId
{
get
{
string value = _ProviderId;
GetProviderId(ref value);
return (_ProviderId = value);
}
set
{
string oldValue = _ProviderId;
SetProviderId(oldValue, ref value);
if (oldValue != value)
{
_ProviderId = value;
}
}
}
/// <summary>
/// Required
/// </summary>
public virtual global::Jellyfin.Data.Entities.MetadataProvider MetadataProvider { get; set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
}
public void OnSavingChanges()
{
RowVersion++;
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Required
/// </summary>
[ForeignKey("MetadataProvider_Id")]
public virtual MetadataProvider MetadataProvider { get; set; }
}
}

View File

@ -1,84 +1,69 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Movie: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
public partial class Movie : LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Movie(): base()
{
Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Movie()
{
Releases = new HashSet<Release>();
MovieMetadata = new HashSet<MovieMetadata>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Movie CreateMovieUnsafe()
{
return new Movie();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Movie CreateMovieUnsafe()
{
return new Movie();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public Movie(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public Movie(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.Releases = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Release>();
this.MovieMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MovieMetadata>();
this.Releases = new HashSet<Release>();
this.MovieMetadata = new HashSet<MovieMetadata>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static Movie Create(Guid urlid, DateTime dateadded)
{
return new Movie(urlid, dateadded);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static Movie Create(Guid urlid, DateTime dateadded)
{
return new Movie(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
public virtual ICollection<global::Jellyfin.Data.Entities.Release> Releases { get; protected set; }
[ForeignKey("Release_Releases_Id")]
public virtual ICollection<Release> Releases { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.MovieMetadata> MovieMetadata { get; protected set; }
[ForeignKey("MovieMetadata_MovieMetadata_Id")]
public virtual ICollection<MovieMetadata> MovieMetadata { get; protected set; }
}
}
}

View File

@ -1,239 +1,223 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MovieMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
public partial class MovieMetadata : Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MovieMetadata(): base()
{
Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MovieMetadata()
{
Studios = new HashSet<Company>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MovieMetadata CreateMovieMetadataUnsafe()
{
return new MovieMetadata();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MovieMetadata CreateMovieMetadataUnsafe()
{
return new MovieMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_movie0"></param>
public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_movie0"></param>
public MovieMetadata(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0));
_movie0.MovieMetadata.Add(this);
if (_movie0 == null) throw new ArgumentNullException(nameof(_movie0));
_movie0.MovieMetadata.Add(this);
this.Studios = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
this.Studios = new HashSet<Company>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_movie0"></param>
public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.Movie _movie0)
{
return new MovieMetadata(title, language, dateadded, datemodified, _movie0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_movie0"></param>
public static MovieMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, Movie _movie0)
{
return new MovieMetadata(title, language, dateadded, datemodified, _movie0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Outline
/// </summary>
protected string _Outline;
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before setting.
/// </summary>
partial void SetOutline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before returning.
/// </summary>
partial void GetOutline(ref string result);
/// <summary>
/// Backing field for Outline
/// </summary>
protected string _Outline;
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before setting.
/// </summary>
partial void SetOutline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Outline to be changed before returning.
/// </summary>
partial void GetOutline(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Outline
{
get
{
string value = _Outline;
GetOutline(ref value);
return (_Outline = value);
}
set
{
string oldValue = _Outline;
SetOutline(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Outline
{
get
{
_Outline = value;
string value = _Outline;
GetOutline(ref value);
return (_Outline = value);
}
}
}
/// <summary>
/// Backing field for Plot
/// </summary>
protected string _Plot;
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before setting.
/// </summary>
partial void SetPlot(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before returning.
/// </summary>
partial void GetPlot(ref string result);
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Plot
{
get
{
string value = _Plot;
GetPlot(ref value);
return (_Plot = value);
}
set
{
string oldValue = _Plot;
SetPlot(oldValue, ref value);
if (oldValue != value)
set
{
_Plot = value;
string oldValue = _Outline;
SetOutline(oldValue, ref value);
if (oldValue != value)
{
_Outline = value;
}
}
}
}
}
/// <summary>
/// Backing field for Tagline
/// </summary>
protected string _Tagline;
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before setting.
/// </summary>
partial void SetTagline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before returning.
/// </summary>
partial void GetTagline(ref string result);
/// <summary>
/// Backing field for Plot
/// </summary>
protected string _Plot;
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before setting.
/// </summary>
partial void SetPlot(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Plot to be changed before returning.
/// </summary>
partial void GetPlot(ref string result);
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Tagline
{
get
{
string value = _Tagline;
GetTagline(ref value);
return (_Tagline = value);
}
set
{
string oldValue = _Tagline;
SetTagline(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 65535
/// </summary>
[MaxLength(65535)]
[StringLength(65535)]
public string Plot
{
get
{
_Tagline = value;
string value = _Plot;
GetPlot(ref value);
return (_Plot = value);
}
}
}
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
set
{
_Country = value;
string oldValue = _Plot;
SetPlot(oldValue, ref value);
if (oldValue != value)
{
_Plot = value;
}
}
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Backing field for Tagline
/// </summary>
protected string _Tagline;
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before setting.
/// </summary>
partial void SetTagline(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Tagline to be changed before returning.
/// </summary>
partial void GetTagline(ref string result);
public virtual ICollection<global::Jellyfin.Data.Entities.Company> Studios { get; protected set; }
/// <summary>
/// Max length = 1024
/// </summary>
[MaxLength(1024)]
[StringLength(1024)]
public string Tagline
{
get
{
string value = _Tagline;
GetTagline(ref value);
return (_Tagline = value);
}
set
{
string oldValue = _Tagline;
SetTagline(oldValue, ref value);
if (oldValue != value)
{
_Tagline = value;
}
}
}
}
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
{
_Country = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("Company_Studios_Id")]
public virtual ICollection<Company> Studios { get; protected set; }
}
}

View File

@ -1,84 +1,68 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MusicAlbum: global::Jellyfin.Data.Entities.LibraryItem
{
partial void Init();
public partial class MusicAlbum : LibraryItem
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MusicAlbum(): base()
{
MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>();
Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MusicAlbum()
{
MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>();
Tracks = new HashSet<Track>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MusicAlbum CreateMusicAlbumUnsafe()
{
return new MusicAlbum();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MusicAlbum CreateMusicAlbumUnsafe()
{
return new MusicAlbum();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public MusicAlbum(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public MusicAlbum(Guid urlid, DateTime dateadded)
{
this.UrlId = urlid;
this.MusicAlbumMetadata = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.MusicAlbumMetadata>();
this.Tracks = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Track>();
this.MusicAlbumMetadata = new HashSet<MusicAlbumMetadata>();
this.Tracks = new HashSet<Track>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static MusicAlbum Create(Guid urlid, DateTime dateadded)
{
return new MusicAlbum(urlid, dateadded);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="urlid">This is whats gets displayed in the Urls and API requests. This could also be a string.</param>
public static MusicAlbum Create(Guid urlid, DateTime dateadded)
{
return new MusicAlbum(urlid, dateadded);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id")]
public virtual ICollection<MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.MusicAlbumMetadata> MusicAlbumMetadata { get; protected set; }
[ForeignKey("Track_Tracks_Id")]
public virtual ICollection<Track> Tracks { get; protected set; }
public virtual ICollection<global::Jellyfin.Data.Entities.Track> Tracks { get; protected set; }
}
}
}

View File

@ -1,202 +1,187 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class MusicAlbumMetadata: global::Jellyfin.Data.Entities.Metadata
{
partial void Init();
public partial class MusicAlbumMetadata : Metadata
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MusicAlbumMetadata(): base()
{
Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected MusicAlbumMetadata()
{
Labels = new HashSet<Company>();
Init();
}
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MusicAlbumMetadata CreateMusicAlbumMetadataUnsafe()
{
return new MusicAlbumMetadata();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static MusicAlbumMetadata CreateMusicAlbumMetadataUnsafe()
{
return new MusicAlbumMetadata();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_musicalbum0"></param>
public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_musicalbum0"></param>
public MusicAlbumMetadata(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentNullException(nameof(title));
this.Title = title;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (string.IsNullOrEmpty(language)) throw new ArgumentNullException(nameof(language));
this.Language = language;
if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0));
_musicalbum0.MusicAlbumMetadata.Add(this);
if (_musicalbum0 == null) throw new ArgumentNullException(nameof(_musicalbum0));
_musicalbum0.MusicAlbumMetadata.Add(this);
this.Labels = new System.Collections.Generic.HashSet<global::Jellyfin.Data.Entities.Company>();
this.Labels = new HashSet<Company>();
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_musicalbum0"></param>
public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, global::Jellyfin.Data.Entities.MusicAlbum _musicalbum0)
{
return new MusicAlbumMetadata(title, language, dateadded, datemodified, _musicalbum0);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="title">The title or name of the object</param>
/// <param name="language">ISO-639-3 3-character language codes</param>
/// <param name="_musicalbum0"></param>
public static MusicAlbumMetadata Create(string title, string language, DateTime dateadded, DateTime datemodified, MusicAlbum _musicalbum0)
{
return new MusicAlbumMetadata(title, language, dateadded, datemodified, _musicalbum0);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Backing field for Barcode
/// </summary>
protected string _Barcode;
/// <summary>
/// When provided in a partial class, allows value of Barcode to be changed before setting.
/// </summary>
partial void SetBarcode(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Barcode to be changed before returning.
/// </summary>
partial void GetBarcode(ref string result);
/// <summary>
/// Backing field for Barcode
/// </summary>
protected string _Barcode;
/// <summary>
/// When provided in a partial class, allows value of Barcode to be changed before setting.
/// </summary>
partial void SetBarcode(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Barcode to be changed before returning.
/// </summary>
partial void GetBarcode(ref string result);
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string Barcode
{
get
{
string value = _Barcode;
GetBarcode(ref value);
return (_Barcode = value);
}
set
{
string oldValue = _Barcode;
SetBarcode(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string Barcode
{
get
{
_Barcode = value;
string value = _Barcode;
GetBarcode(ref value);
return (_Barcode = value);
}
}
}
/// <summary>
/// Backing field for LabelNumber
/// </summary>
protected string _LabelNumber;
/// <summary>
/// When provided in a partial class, allows value of LabelNumber to be changed before setting.
/// </summary>
partial void SetLabelNumber(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of LabelNumber to be changed before returning.
/// </summary>
partial void GetLabelNumber(ref string result);
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string LabelNumber
{
get
{
string value = _LabelNumber;
GetLabelNumber(ref value);
return (_LabelNumber = value);
}
set
{
string oldValue = _LabelNumber;
SetLabelNumber(oldValue, ref value);
if (oldValue != value)
set
{
_LabelNumber = value;
string oldValue = _Barcode;
SetBarcode(oldValue, ref value);
if (oldValue != value)
{
_Barcode = value;
}
}
}
}
}
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
/// <summary>
/// Backing field for LabelNumber
/// </summary>
protected string _LabelNumber;
/// <summary>
/// When provided in a partial class, allows value of LabelNumber to be changed before setting.
/// </summary>
partial void SetLabelNumber(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of LabelNumber to be changed before returning.
/// </summary>
partial void GetLabelNumber(ref string result);
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Max length = 255
/// </summary>
[MaxLength(255)]
[StringLength(255)]
public string LabelNumber
{
get
{
_Country = value;
string value = _LabelNumber;
GetLabelNumber(ref value);
return (_LabelNumber = value);
}
}
}
set
{
string oldValue = _LabelNumber;
SetLabelNumber(oldValue, ref value);
if (oldValue != value)
{
_LabelNumber = value;
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
/// <summary>
/// Backing field for Country
/// </summary>
protected string _Country;
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before setting.
/// </summary>
partial void SetCountry(string oldValue, ref string newValue);
/// <summary>
/// When provided in a partial class, allows value of Country to be changed before returning.
/// </summary>
partial void GetCountry(ref string result);
public virtual ICollection<global::Jellyfin.Data.Entities.Company> Labels { get; protected set; }
/// <summary>
/// Max length = 2
/// </summary>
[MaxLength(2)]
[StringLength(2)]
public string Country
{
get
{
string value = _Country;
GetCountry(ref value);
return (_Country = value);
}
set
{
string oldValue = _Country;
SetCountry(oldValue, ref value);
if (oldValue != value)
{
_Country = value;
}
}
}
}
/*************************************************************************
* Navigation properties
*************************************************************************/
[ForeignKey("Company_Labels_Id")]
public virtual ICollection<Company> Labels { get; protected set; }
}
}

View File

@ -1,152 +1,144 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
//
// Produced by Entity Framework Visual Editor
// https://github.com/msawczyn/EFDesigner
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Jellyfin.Data.Entities
{
public partial class Permission
{
partial void Init();
public partial class Permission
{
partial void Init();
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Permission()
{
Init();
}
/// <summary>
/// Default constructor. Protected due to required properties, but present because EF needs it.
/// </summary>
protected Permission()
{
Init();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Permission CreatePermissionUnsafe()
{
return new Permission();
}
/// <summary>
/// Replaces default constructor, since it's protected. Caller assumes responsibility for setting all required values before saving.
/// </summary>
public static Permission CreatePermissionUnsafe()
{
return new Permission();
}
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="kind"></param>
/// <param name="value"></param>
/// <param name="_user0"></param>
/// <param name="_group1"></param>
public Permission(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
{
this.Kind = kind;
/// <summary>
/// Public constructor with required data
/// </summary>
/// <param name="kind"></param>
/// <param name="value"></param>
/// <param name="_user0"></param>
/// <param name="_group1"></param>
public Permission(Enums.PermissionKind kind, bool value, User _user0, Group _group1)
{
this.Kind = kind;
this.Value = value;
this.Value = value;
if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
_user0.Permissions.Add(this);
if (_user0 == null) throw new ArgumentNullException(nameof(_user0));
_user0.Permissions.Add(this);
if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
_group1.GroupPermissions.Add(this);
if (_group1 == null) throw new ArgumentNullException(nameof(_group1));
_group1.GroupPermissions.Add(this);
Init();
}
Init();
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="kind"></param>
/// <param name="value"></param>
/// <param name="_user0"></param>
/// <param name="_group1"></param>
public static Permission Create(global::Jellyfin.Data.Enums.PermissionKind kind, bool value, global::Jellyfin.Data.Entities.User _user0, global::Jellyfin.Data.Entities.Group _group1)
{
return new Permission(kind, value, _user0, _group1);
}
/// <summary>
/// Static create function (for use in LINQ queries, etc.)
/// </summary>
/// <param name="kind"></param>
/// <param name="value"></param>
/// <param name="_user0"></param>
/// <param name="_group1"></param>
public static Permission Create(Enums.PermissionKind kind, bool value, User _user0, Group _group1)
{
return new Permission(kind, value, _user0, _group1);
}
/*************************************************************************
* Properties
*************************************************************************/
/*************************************************************************
* Properties
*************************************************************************/
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
public int Id { get; protected set; }
/// <summary>
/// Identity, Indexed, Required
/// </summary>
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; protected set; }
/// <summary>
/// Backing field for Kind
/// </summary>
protected global::Jellyfin.Data.Enums.PermissionKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(global::Jellyfin.Data.Enums.PermissionKind oldValue, ref global::Jellyfin.Data.Enums.PermissionKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref global::Jellyfin.Data.Enums.PermissionKind result);
/// <summary>
/// Backing field for Kind
/// </summary>
protected Enums.PermissionKind _Kind;
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before setting.
/// </summary>
partial void SetKind(Enums.PermissionKind oldValue, ref Enums.PermissionKind newValue);
/// <summary>
/// When provided in a partial class, allows value of Kind to be changed before returning.
/// </summary>
partial void GetKind(ref Enums.PermissionKind result);
/// <summary>
/// Required
/// </summary>
[Required]
public global::Jellyfin.Data.Enums.PermissionKind Kind
{
get
{
global::Jellyfin.Data.Enums.PermissionKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
set
{
global::Jellyfin.Data.Enums.PermissionKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
/// <summary>
/// Required
/// </summary>
[Required]
public Enums.PermissionKind Kind
{
get
{
_Kind = value;
OnPropertyChanged();
Enums.PermissionKind value = _Kind;
GetKind(ref value);
return (_Kind = value);
}
}
}
set
{
Enums.PermissionKind oldValue = _Kind;
SetKind(oldValue, ref value);
if (oldValue != value)
{
_Kind = value;
OnPropertyChanged();
}
}
}
/// <summary>
/// Required
/// </summary>
[Required]
public bool Value { get; set; }
/// <summary>
/// Required
/// </summary>
[Required]
public bool Value { get; set; }
/// <summary>
/// Concurrency token
/// </summary>
[Timestamp]
public Byte[] Timestamp { get; set; }
/// <summary>
/// Required, ConcurrenyToken
/// </summary>
[ConcurrencyCheck]
[Required]
public uint RowVersion { get; set; }
/*************************************************************************
* Navigation properties
*************************************************************************/
public void OnSavingChanges()
{
RowVersion++;
}
public virtual event PropertyChangedEventHandler PropertyChanged;
/*************************************************************************
* Navigation properties
*************************************************************************/
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public virtual event PropertyChangedEventHandler PropertyChanged;
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

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