diff --git a/.editorconfig b/.editorconfig
index dc9aaa3ed5..b84e563efa 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -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
diff --git a/DvdLib/BigEndianBinaryReader.cs b/DvdLib/BigEndianBinaryReader.cs
index 473005b556..b3aad85cec 100644
--- a/DvdLib/BigEndianBinaryReader.cs
+++ b/DvdLib/BigEndianBinaryReader.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Buffers.Binary;
using System.IO;
diff --git a/DvdLib/DvdLib.csproj b/DvdLib/DvdLib.csproj
index fd0cb5e255..64d041cb05 100644
--- a/DvdLib/DvdLib.csproj
+++ b/DvdLib/DvdLib.csproj
@@ -13,6 +13,7 @@
netstandard2.1
false
true
+ true
diff --git a/DvdLib/Ifo/Cell.cs b/DvdLib/Ifo/Cell.cs
index 268ab897ee..2eab400f7d 100644
--- a/DvdLib/Ifo/Cell.cs
+++ b/DvdLib/Ifo/Cell.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
namespace DvdLib.Ifo
diff --git a/DvdLib/Ifo/CellPlaybackInfo.cs b/DvdLib/Ifo/CellPlaybackInfo.cs
index e588e51ac0..6e33a0ec5a 100644
--- a/DvdLib/Ifo/CellPlaybackInfo.cs
+++ b/DvdLib/Ifo/CellPlaybackInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
namespace DvdLib.Ifo
diff --git a/DvdLib/Ifo/CellPositionInfo.cs b/DvdLib/Ifo/CellPositionInfo.cs
index 2b973e0830..216aa0f77a 100644
--- a/DvdLib/Ifo/CellPositionInfo.cs
+++ b/DvdLib/Ifo/CellPositionInfo.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.IO;
namespace DvdLib.Ifo
diff --git a/DvdLib/Ifo/Chapter.cs b/DvdLib/Ifo/Chapter.cs
index bd3bd97040..1e69429f82 100644
--- a/DvdLib/Ifo/Chapter.cs
+++ b/DvdLib/Ifo/Chapter.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
namespace DvdLib.Ifo
{
public class Chapter
diff --git a/DvdLib/Ifo/Dvd.cs b/DvdLib/Ifo/Dvd.cs
index 5af58a2dc8..ca20baa73f 100644
--- a/DvdLib/Ifo/Dvd.cs
+++ b/DvdLib/Ifo/Dvd.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/DvdLib/Ifo/DvdTime.cs b/DvdLib/Ifo/DvdTime.cs
index 3688089ec7..978af90c2e 100644
--- a/DvdLib/Ifo/DvdTime.cs
+++ b/DvdLib/Ifo/DvdTime.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace DvdLib.Ifo
diff --git a/DvdLib/Ifo/Program.cs b/DvdLib/Ifo/Program.cs
index af08afa356..9f62512706 100644
--- a/DvdLib/Ifo/Program.cs
+++ b/DvdLib/Ifo/Program.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
namespace DvdLib.Ifo
diff --git a/DvdLib/Ifo/ProgramChain.cs b/DvdLib/Ifo/ProgramChain.cs
index 7b003005b9..4860360afd 100644
--- a/DvdLib/Ifo/ProgramChain.cs
+++ b/DvdLib/Ifo/ProgramChain.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.IO;
using System.Linq;
diff --git a/DvdLib/Ifo/Title.cs b/DvdLib/Ifo/Title.cs
index 335e929928..abf806d2c0 100644
--- a/DvdLib/Ifo/Title.cs
+++ b/DvdLib/Ifo/Title.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System.Collections.Generic;
using System.IO;
diff --git a/DvdLib/Ifo/UserOperation.cs b/DvdLib/Ifo/UserOperation.cs
index 757a5a05db..5d111ebc06 100644
--- a/DvdLib/Ifo/UserOperation.cs
+++ b/DvdLib/Ifo/UserOperation.cs
@@ -1,3 +1,5 @@
+#pragma warning disable CS1591
+
using System;
namespace DvdLib.Ifo
diff --git a/Emby.Naming/Video/VideoResolver.cs b/Emby.Naming/Video/VideoResolver.cs
index 0b75a8cce9..b4aee614b0 100644
--- a/Emby.Naming/Video/VideoResolver.cs
+++ b/Emby.Naming/Video/VideoResolver.cs
@@ -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 newName))
+ && TryCleanString(name, out ReadOnlySpan newName))
{
name = newName.ToString();
}
-
- year = cleanDateTimeResult.Year;
}
return new VideoFileInfo
diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs
index 11fed24f7a..74863b8057 100644
--- a/Emby.Server.Implementations/ApplicationHost.cs
+++ b/Emby.Server.Implementations/ApplicationHost.cs
@@ -519,13 +519,6 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton();
- // TODO: Remove support for injecting ILogger completely
- serviceCollection.AddSingleton((provider) =>
- {
- Logger.LogWarning("Injecting ILogger directly is deprecated and should be replaced with ILogger");
- return Logger;
- });
-
serviceCollection.AddSingleton(_fileSystemManager);
serviceCollection.AddSingleton();
@@ -1122,9 +1115,6 @@ namespace Emby.Server.Implementations
ItemsByNamePath = ApplicationPaths.InternalMetadataPath,
InternalMetadataPath = ApplicationPaths.InternalMetadataPath,
CachePath = ApplicationPaths.CachePath,
- HttpServerPortNumber = HttpPort,
- SupportsHttps = SupportsHttps,
- HttpsPortNumber = HttpsPort,
OperatingSystem = OperatingSystem.Id.ToString(),
OperatingSystemDisplayName = OperatingSystem.Name,
CanSelfRestart = CanSelfRestart,
@@ -1160,23 +1150,22 @@ namespace Emby.Server.Implementations
};
}
- public bool EnableHttps => SupportsHttps && ServerConfigurationManager.Configuration.EnableHttps;
+ ///
+ public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.Configuration.EnableHttps;
- public bool SupportsHttps => Certificate != null || ServerConfigurationManager.Configuration.IsBehindProxy;
-
- public async Task GetLocalApiUrl(CancellationToken cancellationToken, bool forceHttp = false)
+ ///
+ public async Task 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)
{
@@ -1203,7 +1192,7 @@ namespace Emby.Server.Implementations
}
///
- public string GetLocalApiUrl(IPAddress ipAddress, bool forceHttp = false)
+ public string GetLocalApiUrl(IPAddress ipAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
@@ -1213,29 +1202,30 @@ namespace Emby.Server.Implementations
str.CopyTo(span.Slice(1));
span[^1] = ']';
- return GetLocalApiUrl(span, forceHttp);
+ return GetLocalApiUrl(span);
}
- return GetLocalApiUrl(ipAddress.ToString(), forceHttp);
+ return GetLocalApiUrl(ipAddress.ToString());
}
- ///
- public string GetLocalApiUrl(ReadOnlySpan host, bool forceHttp = false)
+ ///
+ 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)
+ ///
+ public string GetLocalApiUrl(ReadOnlySpan 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> GetLocalIpAddresses(CancellationToken cancellationToken)
@@ -1269,7 +1259,7 @@ namespace Emby.Server.Implementations
}
}
- var valid = await IsIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
+ var valid = await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false);
if (valid)
{
resultList.Add(address);
@@ -1303,7 +1293,7 @@ namespace Emby.Server.Implementations
private readonly ConcurrentDictionary _validAddressResults = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase);
- private async Task IsIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken)
+ private async Task IsLocalIpAddressValidAsync(IPAddress address, CancellationToken cancellationToken)
{
if (address.Equals(IPAddress.Loopback)
|| address.Equals(IPAddress.IPv6Loopback))
@@ -1311,8 +1301,7 @@ namespace Emby.Server.Implementations
return true;
}
- var apiUrl = GetLocalApiUrl(address);
- apiUrl += "/system/ping";
+ var apiUrl = GetLocalApiUrl(address) + "/system/ping";
if (_validAddressResults.TryGetValue(apiUrl, out var cachedResult))
{
diff --git a/Emby.Server.Implementations/Browser/BrowserLauncher.cs b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
index 96096e142a..7f7c6a0be4 100644
--- a/Emby.Server.Implementations/Browser/BrowserLauncher.cs
+++ b/Emby.Server.Implementations/Browser/BrowserLauncher.cs
@@ -31,18 +31,18 @@ namespace Emby.Server.Implementations.Browser
/// Opens the specified URL in an external browser window. Any exceptions will be logged, but ignored.
///
/// The application host.
- /// The URL.
- private static void TryOpenUrl(IServerApplicationHost appHost, string url)
+ /// The URL to open, relative to the server base URL.
+ 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();
- logger?.LogError(ex, "Failed to open browser window with URL {URL}", url);
+ logger?.LogError(ex, "Failed to open browser window with URL {URL}", relativeUrl);
}
}
}
diff --git a/Emby.Server.Implementations/ConfigurationOptions.cs b/Emby.Server.Implementations/ConfigurationOptions.cs
index db7c35a7c8..dea9b6682a 100644
--- a/Emby.Server.Implementations/ConfigurationOptions.cs
+++ b/Emby.Server.Implementations/ConfigurationOptions.cs
@@ -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
diff --git a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
index 22955850ab..6ee6230fc6 100644
--- a/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteUserDataRepository.cs
@@ -375,5 +375,15 @@ namespace Emby.Server.Implementations.Data
return userData;
}
+
+ ///
+ ///
+ /// There is nothing to dispose here since and
+ /// are managed by .
+ /// See .
+ ///
+ protected override void Dispose(bool dispose)
+ {
+ }
}
}
diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
index 37d7fd4799..878cee23c4 100644
--- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
+++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs
@@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.EntryPoints
.Append(config.PublicHttpsPort).Append(Separator)
.Append(_appHost.HttpPort).Append(Separator)
.Append(_appHost.HttpsPort).Append(Separator)
- .Append(_appHost.EnableHttps).Append(Separator)
+ .Append(_appHost.ListenWithHttps).Append(Separator)
.Append(config.EnableRemoteAccess).Append(Separator)
.ToString();
}
@@ -158,7 +158,7 @@ namespace Emby.Server.Implementations.EntryPoints
{
yield return CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort);
- if (_appHost.EnableHttps)
+ if (_appHost.ListenWithHttps)
{
yield return CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort);
}
diff --git a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
index 7358c1a81d..81e793f5c7 100644
--- a/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/Emby.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -366,11 +366,14 @@ namespace Emby.Server.Implementations.HttpServer
return true;
}
+ ///
+ /// Validate a connection from a remote IP address to a URL to see if a redirection to HTTPS is required.
+ ///
+ /// True if the request is valid, or false if the request is not valid and an HTTPS redirect is required.
private bool ValidateSsl(string remoteIp, string urlString)
{
if (_config.Configuration.RequireHttps
- && _appHost.EnableHttps
- && !_config.Configuration.IsBehindProxy
+ && _appHost.ListenWithHttps
&& !urlString.Contains("https://", StringComparison.OrdinalIgnoreCase))
{
// These are hacks, but if these ever occur on ipv6 in the local network they could be incorrectly redirected
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 85b1b6e323..6c9ba7c272 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -16,7 +16,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
///
public class MusicAlbumResolver : ItemResolver
{
- private readonly ILogger _logger;
+ private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly ILibraryManager _libraryManager;
@@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
/// The logger.
/// The file system.
/// The library manager.
- public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager)
+ public MusicAlbumResolver(ILogger logger, IFileSystem fileSystem, ILibraryManager libraryManager)
{
_logger = logger;
_fileSystem = fileSystem;
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
index 681db4896e..5f5cd0e928 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
@@ -15,7 +15,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
///
public class MusicArtistResolver : ItemResolver
{
- private readonly ILogger _logger;
+ private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly ILibraryManager _libraryManager;
private readonly IServerConfigurationManager _config;
@@ -23,12 +23,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
///
/// Initializes a new instance of the class.
///
- /// The logger.
+ /// The logger for the created instances.
/// The file system.
/// The library manager.
/// The configuration manager.
public MusicArtistResolver(
- ILogger logger,
+ ILogger logger,
IFileSystem fileSystem,
ILibraryManager libraryManager,
IServerConfigurationManager config)
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index d63bc6bda8..b8feb5535f 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -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);
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 33f4ca1465..3efe1ee253 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1059,7 +1059,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
var stream = new MediaSourceInfo
{
- EncoderPath = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
+ EncoderPath = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveRecordings/" + info.Id + "/stream",
EncoderProtocol = MediaProtocol.Http,
Path = info.Path,
Protocol = MediaProtocol.File,
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
index d89a816b3b..82b1f3cf1f 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs
@@ -121,7 +121,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
- MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
+ MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Protocol = MediaProtocol.Http;
//OpenedMediaSource.SupportsDirectPlay = false;
//OpenedMediaSource.SupportsDirectStream = true;
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index f5dda79db3..f7c9c736e3 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -35,7 +35,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
public M3UTunerHost(
IServerConfigurationManager config,
IMediaSourceManager mediaSourceManager,
- ILogger logger,
+ ILogger logger,
IJsonSerializer jsonSerializer,
IFileSystem fileSystem,
IHttpClient httpClient,
@@ -83,7 +83,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
return Task.FromResult(list);
}
- private static readonly string[] _disallowedSharedStreamExtensions = new string[]
+ private static readonly string[] _disallowedSharedStreamExtensions =
{
".mkv",
".mp4",
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
index 0e600202aa..083fcd0299 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs
@@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
- MediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1", true) + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
+ MediaSource.Path = _appHost.GetLoopbackHttpApiUrl() + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
MediaSource.Protocol = MediaProtocol.Http;
//OpenedMediaSource.Path = TempFilePath;
diff --git a/Emby.Server.Implementations/Localization/Core/af.json b/Emby.Server.Implementations/Localization/Core/af.json
index 1363eaf854..20447347b3 100644
--- a/Emby.Server.Implementations/Localization/Core/af.json
+++ b/Emby.Server.Implementations/Localization/Core/af.json
@@ -4,7 +4,7 @@
"Folders": "Fouers",
"Favorites": "Gunstelinge",
"HeaderFavoriteShows": "Gunsteling Vertonings",
- "ValueSpecialEpisodeName": "Spesiaal - {0}",
+ "ValueSpecialEpisodeName": "Spesiale - {0}",
"HeaderAlbumArtists": "Album Kunstenaars",
"Books": "Boeke",
"HeaderNextUp": "Volgende",
diff --git a/Emby.Server.Implementations/Localization/Core/bn.json b/Emby.Server.Implementations/Localization/Core/bn.json
index ef7792356a..4949b10e6a 100644
--- a/Emby.Server.Implementations/Localization/Core/bn.json
+++ b/Emby.Server.Implementations/Localization/Core/bn.json
@@ -91,5 +91,7 @@
"HeaderNextUp": "এরপরে আসছে",
"HeaderLiveTV": "লাইভ টিভি",
"HeaderFavoriteSongs": "প্রিয় গানগুলো",
- "HeaderFavoriteShows": "প্রিয় শোগুলো"
+ "HeaderFavoriteShows": "প্রিয় শোগুলো",
+ "TasksLibraryCategory": "গ্রন্থাগার",
+ "TasksMaintenanceCategory": "রক্ষণাবেক্ষণ"
}
diff --git a/Emby.Server.Implementations/Localization/Core/es-MX.json b/Emby.Server.Implementations/Localization/Core/es-MX.json
index e0bbe90b36..d93920f433 100644
--- a/Emby.Server.Implementations/Localization/Core/es-MX.json
+++ b/Emby.Server.Implementations/Localization/Core/es-MX.json
@@ -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",
diff --git a/Emby.Server.Implementations/Localization/Core/es.json b/Emby.Server.Implementations/Localization/Core/es.json
index de1baada84..e7bd3959bf 100644
--- a/Emby.Server.Implementations/Localization/Core/es.json
+++ b/Emby.Server.Implementations/Localization/Core/es.json
@@ -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}",
diff --git a/Emby.Server.Implementations/Localization/Core/fr-CA.json b/Emby.Server.Implementations/Localization/Core/fr-CA.json
index 2c9dae6a17..c2349ba5bb 100644
--- a/Emby.Server.Implementations/Localization/Core/fr-CA.json
+++ b/Emby.Server.Implementations/Localization/Core/fr-CA.json
@@ -94,5 +94,23 @@
"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 des sous-titres manquants",
+ "TaskRefreshChannelsDescription": "Rafraîchit des informations des chaines d'internet.",
+ "TaskRefreshChannels": "Rafraîchir des chaines",
+ "TaskCleanTranscodeDescription": "Retirer des fichiers de transcodage de plus qu'un jour.",
+ "TaskCleanTranscode": "Nettoyer le directoire de transcodage",
+ "TaskUpdatePluginsDescription": "Télécharger et installer des mises à jours des plugins qui sont configurés m.à.j. automisés.",
+ "TaskUpdatePlugins": "Mise à jour des plugins",
+ "TaskRefreshPeopleDescription": "Met à jour les métadonnées pour les acteurs et réalisateurs dans votre bibliothèque.",
+ "TaskRefreshPeople": "Rafraîchir les acteurs",
+ "TaskCleanLogsDescription": "Retire les données qui ont plus que {0} jours.",
+ "TaskCleanLogs": "Nettoyer les données de directoire",
+ "TaskRefreshLibraryDescription": "Analyse votre bibliothèque média pour des nouveaux fichiers et rafraîchit les métadonnées.",
+ "TaskRefreshChapterImages": "Extraire des images du chapitre",
+ "TaskRefreshChapterImagesDescription": "Créer des vignettes pour des vidéos qui ont des chapitres",
+ "TaskRefreshLibrary": "Analyser la bibliothèque de média",
+ "TaskCleanCache": "Nettoyer le cache de directoire",
+ "TasksApplicationCategory": "Application"
}
diff --git a/Emby.Server.Implementations/Localization/Core/gsw.json b/Emby.Server.Implementations/Localization/Core/gsw.json
index 9611e33f57..8780a884ba 100644
--- a/Emby.Server.Implementations/Localization/Core/gsw.json
+++ b/Emby.Server.Implementations/Localization/Core/gsw.json
@@ -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."
}
diff --git a/Emby.Server.Implementations/Localization/Core/he.json b/Emby.Server.Implementations/Localization/Core/he.json
index 8abe31d2a0..4e54b9f7ad 100644
--- a/Emby.Server.Implementations/Localization/Core/he.json
+++ b/Emby.Server.Implementations/Localization/Core/he.json
@@ -99,5 +99,13 @@
"TaskCleanCache": "נקה תיקיית מטמון",
"TasksApplicationCategory": "יישום",
"TasksLibraryCategory": "ספרייה",
- "TasksMaintenanceCategory": "תחזוקה"
+ "TasksMaintenanceCategory": "תחזוקה",
+ "TaskUpdatePlugins": "עדכן תוספים",
+ "TaskRefreshPeopleDescription": "מעדכן מטא נתונים עבור שחקנים ובמאים בספריית המדיה שלך.",
+ "TaskRefreshPeople": "רענן אנשים",
+ "TaskCleanLogsDescription": "מוחק קבצי יומן בני יותר מ- {0} ימים.",
+ "TaskCleanLogs": "נקה תיקיית יומן",
+ "TaskRefreshLibraryDescription": "סורק את ספריית המדיה שלך אחר קבצים חדשים ומרענן מטא נתונים.",
+ "TaskRefreshChapterImagesDescription": "יוצר תמונות ממוזערות לסרטונים שיש להם פרקים.",
+ "TasksChannelsCategory": "ערוצי אינטרנט"
}
diff --git a/Emby.Server.Implementations/Localization/Core/hr.json b/Emby.Server.Implementations/Localization/Core/hr.json
index 6947178d7a..c169a35e79 100644
--- a/Emby.Server.Implementations/Localization/Core/hr.json
+++ b/Emby.Server.Implementations/Localization/Core/hr.json
@@ -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"
}
diff --git a/Emby.Server.Implementations/Localization/Core/it.json b/Emby.Server.Implementations/Localization/Core/it.json
index 0758bbe9ce..7f5a56e86c 100644
--- a/Emby.Server.Implementations/Localization/Core/it.json
+++ b/Emby.Server.Implementations/Localization/Core/it.json
@@ -5,7 +5,7 @@
"Artists": "Artisti",
"AuthenticationSucceededWithUserName": "{0} autenticato con successo",
"Books": "Libri",
- "CameraImageUploadedFrom": "È stata caricata una nuova immagine della fotocamera dal device {0}",
+ "CameraImageUploadedFrom": "È stata caricata una nuova fotografia da {0}",
"Channels": "Canali",
"ChapterNameValue": "Capitolo {0}",
"Collections": "Collezioni",
diff --git a/Emby.Server.Implementations/Localization/Core/mk.json b/Emby.Server.Implementations/Localization/Core/mk.json
index 8df137302f..bbdf99abab 100644
--- a/Emby.Server.Implementations/Localization/Core/mk.json
+++ b/Emby.Server.Implementations/Localization/Core/mk.json
@@ -91,5 +91,12 @@
"Songs": "Песни",
"Shows": "Серии",
"ServerNameNeedsToBeRestarted": "{0} треба да се рестартира",
- "ScheduledTaskStartedWithName": "{0} започна"
+ "ScheduledTaskStartedWithName": "{0} започна",
+ "TaskRefreshChapterImages": "Извези Слики од Поглавје",
+ "TaskCleanCacheDescription": "Ги брише кешираните фајлови што не се повеќе потребни од системот.",
+ "TaskCleanCache": "Исчисти Го Кешот",
+ "TasksChannelsCategory": "Интернет Канали",
+ "TasksApplicationCategory": "Апликација",
+ "TasksLibraryCategory": "Библиотека",
+ "TasksMaintenanceCategory": "Одржување"
}
diff --git a/Emby.Server.Implementations/Localization/Core/nl.json b/Emby.Server.Implementations/Localization/Core/nl.json
index baa12e98ec..41c74d54de 100644
--- a/Emby.Server.Implementations/Localization/Core/nl.json
+++ b/Emby.Server.Implementations/Localization/Core/nl.json
@@ -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",
diff --git a/Emby.Server.Implementations/Localization/Core/sl-SI.json b/Emby.Server.Implementations/Localization/Core/sl-SI.json
index b60dd33bd5..60c58d472d 100644
--- a/Emby.Server.Implementations/Localization/Core/sl-SI.json
+++ b/Emby.Server.Implementations/Localization/Core/sl-SI.json
@@ -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"
}
diff --git a/Emby.Server.Implementations/Localization/Core/uk.json b/Emby.Server.Implementations/Localization/Core/uk.json
new file mode 100644
index 0000000000..b2e0b66fe1
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/uk.json
@@ -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": "Альбоми"
+}
diff --git a/Emby.Server.Implementations/Localization/Core/zh-HK.json b/Emby.Server.Implementations/Localization/Core/zh-HK.json
index 224748e611..a67a67582f 100644
--- a/Emby.Server.Implementations/Localization/Core/zh-HK.json
+++ b/Emby.Server.Implementations/Localization/Core/zh-HK.json
@@ -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": "應用程式"
}
diff --git a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
index 9c638f4395..ee5131c1ff 100644
--- a/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
+++ b/Emby.Server.Implementations/SocketSharp/WebSocketSharpRequest.cs
@@ -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;
diff --git a/Jellyfin.Data/DbContexts/Jellyfin.cs b/Jellyfin.Data/DbContexts/Jellyfin.cs
deleted file mode 100644
index fd488ce7d7..0000000000
--- a/Jellyfin.Data/DbContexts/Jellyfin.cs
+++ /dev/null
@@ -1,1140 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// 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
-//
-//------------------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.ComponentModel.DataAnnotations.Schema;
-using Microsoft.EntityFrameworkCore;
-
-namespace Jellyfin.Data.DbContexts
-{
- ///
- public partial class Jellyfin : DbContext
- {
- #region DbSets
- public virtual Microsoft.EntityFrameworkCore.DbSet Artwork { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Books { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet BookMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Chapters { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Collections { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet CollectionItems { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Companies { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet CompanyMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet CustomItems { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet CustomItemMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Episodes { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet EpisodeMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Genres { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Groups { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Libraries { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet LibraryItems { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet LibraryRoot { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet MediaFiles { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet MediaFileStream { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Metadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet MetadataProviders { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet MetadataProviderIds { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Movies { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet MovieMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet MusicAlbums { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet MusicAlbumMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Permissions { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet People { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet PersonRoles { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Photo { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet PhotoMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Preferences { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet ProviderMappings { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Ratings { get; set; }
-
- ///
- /// Repository for global::Jellyfin.Data.Entities.RatingSource - This is the entity to
- /// store review ratings, not age ratings
- ///
- public virtual Microsoft.EntityFrameworkCore.DbSet RatingSources { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Releases { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Seasons { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet SeasonMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Series { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet SeriesMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Tracks { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet TrackMetadata { get; set; }
- public virtual Microsoft.EntityFrameworkCore.DbSet Users { get; set; }
- #endregion DbSets
-
- ///
- /// Default connection string
- ///
- public static string ConnectionString { get; set; } = @"Data Source=jellyfin.db";
-
- ///
- public Jellyfin(DbContextOptions options) : base(options)
- {
- }
-
- partial void CustomInit(DbContextOptionsBuilder optionsBuilder);
-
- ///
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- CustomInit(optionsBuilder);
- }
-
- partial void OnModelCreatingImpl(ModelBuilder modelBuilder);
- partial void OnModelCreatedImpl(ModelBuilder modelBuilder);
-
- ///
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- base.OnModelCreating(modelBuilder);
- OnModelCreatingImpl(modelBuilder);
-
- modelBuilder.HasDefaultSchema("jellyfin");
-
- modelBuilder.Entity()
- .ToTable("Artwork")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Path)
- .HasMaxLength(65535)
- .IsRequired()
- .HasField("_Path")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Kind)
- .IsRequired()
- .HasField("_Kind")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity().HasIndex(t => t.Kind);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
-
- modelBuilder.Entity()
- .HasMany(x => x.BookMetadata)
- .WithOne()
- .HasForeignKey("BookMetadata_BookMetadata_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Releases)
- .WithOne()
- .HasForeignKey("Release_Releases_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .Property(t => t.ISBN)
- .HasField("_ISBN")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .HasMany(x => x.Publishers)
- .WithOne()
- .HasForeignKey("Company_Publishers_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("Chapter")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(1024)
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Language)
- .HasMaxLength(3)
- .IsRequired()
- .HasField("_Language")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.TimeStart)
- .IsRequired()
- .HasField("_TimeStart")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.TimeEnd)
- .HasField("_TimeEnd")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
-
- modelBuilder.Entity()
- .ToTable("Collection")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(1024)
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasMany(x => x.CollectionItem)
- .WithOne()
- .HasForeignKey("CollectionItem_CollectionItem_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("CollectionItem")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasOne(x => x.LibraryItem)
- .WithOne()
- .HasForeignKey("LibraryItem_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasOne(x => x.Next)
- .WithOne()
- .HasForeignKey("CollectionItem_Next_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasOne(x => x.Previous)
- .WithOne()
- .HasForeignKey("CollectionItem_Previous_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("Company")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasMany(x => x.CompanyMetadata)
- .WithOne()
- .HasForeignKey("CompanyMetadata_CompanyMetadata_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasOne(x => x.Parent)
- .WithOne()
- .HasForeignKey("Company_Parent_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .Property(t => t.Description)
- .HasMaxLength(65535)
- .HasField("_Description")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Headquarters)
- .HasMaxLength(255)
- .HasField("_Headquarters")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Country)
- .HasMaxLength(2)
- .HasField("_Country")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Homepage)
- .HasMaxLength(1024)
- .HasField("_Homepage")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
-
- modelBuilder.Entity()
- .HasMany(x => x.CustomItemMetadata)
- .WithOne()
- .HasForeignKey("CustomItemMetadata_CustomItemMetadata_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Releases)
- .WithOne()
- .HasForeignKey("Release_Releases_Id")
- .IsRequired();
-
-
- modelBuilder.Entity()
- .Property(t => t.EpisodeNumber)
- .HasField("_EpisodeNumber")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .HasMany(x => x.Releases)
- .WithOne()
- .HasForeignKey("Release_Releases_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.EpisodeMetadata)
- .WithOne()
- .HasForeignKey("EpisodeMetadata_EpisodeMetadata_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .Property(t => t.Outline)
- .HasMaxLength(1024)
- .HasField("_Outline")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Plot)
- .HasMaxLength(65535)
- .HasField("_Plot")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Tagline)
- .HasMaxLength(1024)
- .HasField("_Tagline")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
-
- modelBuilder.Entity()
- .ToTable("Genre")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(255)
- .IsRequired()
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity().HasIndex(t => t.Name)
- .IsUnique();
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
-
- modelBuilder.Entity()
- .ToTable("Groups")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(255)
- .IsRequired();
- modelBuilder.Entity().Property("Timestamp").IsConcurrencyToken();
- modelBuilder.Entity()
- .HasMany(x => x.GroupPermissions)
- .WithOne()
- .HasForeignKey("Permission_GroupPermissions_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.ProviderMappings)
- .WithOne()
- .HasForeignKey("ProviderMapping_ProviderMappings_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Preferences)
- .WithOne()
- .HasForeignKey("Preference_Preferences_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("Library")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(1024)
- .IsRequired()
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
-
- modelBuilder.Entity()
- .ToTable("LibraryItem")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.UrlId)
- .IsRequired()
- .HasField("_UrlId")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity().HasIndex(t => t.UrlId)
- .IsUnique();
- modelBuilder.Entity()
- .Property(t => t.DateAdded)
- .IsRequired()
- .HasField("_DateAdded")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasOne(x => x.LibraryRoot)
- .WithOne()
- .HasForeignKey("LibraryRoot_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("LibraryRoot")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Path)
- .HasMaxLength(65535)
- .IsRequired()
- .HasField("_Path")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.NetworkPath)
- .HasMaxLength(65535)
- .HasField("_NetworkPath")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasOne(x => x.Library)
- .WithOne()
- .HasForeignKey("Library_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("MediaFile")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Path)
- .HasMaxLength(65535)
- .IsRequired()
- .HasField("_Path")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Kind)
- .IsRequired()
- .HasField("_Kind")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasMany(x => x.MediaFileStreams)
- .WithOne()
- .HasForeignKey("MediaFileStream_MediaFileStreams_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("MediaFileStream")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.StreamNumber)
- .IsRequired()
- .HasField("_StreamNumber")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
-
- modelBuilder.Entity()
- .ToTable("Metadata")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Title)
- .HasMaxLength(1024)
- .IsRequired()
- .HasField("_Title")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.OriginalTitle)
- .HasMaxLength(1024)
- .HasField("_OriginalTitle")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.SortTitle)
- .HasMaxLength(1024)
- .HasField("_SortTitle")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Language)
- .HasMaxLength(3)
- .IsRequired()
- .HasField("_Language")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.ReleaseDate)
- .HasField("_ReleaseDate")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.DateAdded)
- .IsRequired()
- .HasField("_DateAdded")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.DateModified)
- .IsRequired()
- .HasField("_DateModified")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasMany(x => x.PersonRoles)
- .WithOne()
- .HasForeignKey("PersonRole_PersonRoles_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Genres)
- .WithOne()
- .HasForeignKey("Genre_Genres_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Artwork)
- .WithOne()
- .HasForeignKey("Artwork_Artwork_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Ratings)
- .WithOne()
- .HasForeignKey("Rating_Ratings_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Sources)
- .WithOne()
- .HasForeignKey("MetadataProviderId_Sources_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("MetadataProvider")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(1024)
- .IsRequired()
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
-
- modelBuilder.Entity()
- .ToTable("MetadataProviderId")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.ProviderId)
- .HasMaxLength(255)
- .IsRequired()
- .HasField("_ProviderId")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasOne(x => x.MetadataProvider)
- .WithOne()
- .HasForeignKey("MetadataProvider_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .HasMany(x => x.Releases)
- .WithOne()
- .HasForeignKey("Release_Releases_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.MovieMetadata)
- .WithOne()
- .HasForeignKey("MovieMetadata_MovieMetadata_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .Property(t => t.Outline)
- .HasMaxLength(1024)
- .HasField("_Outline")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Plot)
- .HasMaxLength(65535)
- .HasField("_Plot")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Tagline)
- .HasMaxLength(1024)
- .HasField("_Tagline")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Country)
- .HasMaxLength(2)
- .HasField("_Country")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .HasMany(x => x.Studios)
- .WithOne()
- .HasForeignKey("Company_Studios_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .HasMany(x => x.MusicAlbumMetadata)
- .WithOne()
- .HasForeignKey("MusicAlbumMetadata_MusicAlbumMetadata_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Tracks)
- .WithOne()
- .HasForeignKey("Track_Tracks_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .Property(t => t.Barcode)
- .HasMaxLength(255)
- .HasField("_Barcode")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.LabelNumber)
- .HasMaxLength(255)
- .HasField("_LabelNumber")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Country)
- .HasMaxLength(2)
- .HasField("_Country")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .HasMany(x => x.Labels)
- .WithOne()
- .HasForeignKey("Company_Labels_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("Permissions")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Kind)
- .IsRequired()
- .HasField("_Kind")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Value)
- .IsRequired();
- modelBuilder.Entity().Property("Timestamp").IsConcurrencyToken();
-
- modelBuilder.Entity()
- .ToTable("Person")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.UrlId)
- .IsRequired()
- .HasField("_UrlId")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(1024)
- .IsRequired()
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.SourceId)
- .HasMaxLength(255)
- .HasField("_SourceId")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.DateAdded)
- .IsRequired()
- .HasField("_DateAdded")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.DateModified)
- .IsRequired()
- .HasField("_DateModified")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasMany(x => x.Sources)
- .WithOne()
- .HasForeignKey("MetadataProviderId_Sources_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("PersonRole")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Role)
- .HasMaxLength(1024)
- .HasField("_Role")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Type)
- .IsRequired()
- .HasField("_Type")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasOne(x => x.Person)
- .WithOne()
- .HasForeignKey("Person_Id")
- .IsRequired()
- .OnDelete(DeleteBehavior.Cascade);
- modelBuilder.Entity()
- .HasOne(x => x.Artwork)
- .WithOne()
- .HasForeignKey("Artwork_Artwork_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Sources)
- .WithOne()
- .HasForeignKey("MetadataProviderId_Sources_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .HasMany(x => x.PhotoMetadata)
- .WithOne()
- .HasForeignKey("PhotoMetadata_PhotoMetadata_Id")
- .IsRequired();
- modelBuilder.Entity()
- .HasMany(x => x.Releases)
- .WithOne()
- .HasForeignKey("Release_Releases_Id")
- .IsRequired();
-
-
- modelBuilder.Entity()
- .ToTable("Preferences")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Kind)
- .IsRequired();
- modelBuilder.Entity()
- .Property(t => t.Value)
- .HasMaxLength(65535)
- .IsRequired();
- modelBuilder.Entity().Property("Timestamp").IsConcurrencyToken();
-
- modelBuilder.Entity()
- .ToTable("ProviderMappings")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.ProviderName)
- .HasMaxLength(255)
- .IsRequired();
- modelBuilder.Entity()
- .Property(t => t.ProviderSecrets)
- .HasMaxLength(65535)
- .IsRequired();
- modelBuilder.Entity()
- .Property(t => t.ProviderData)
- .HasMaxLength(65535)
- .IsRequired();
- modelBuilder.Entity().Property("Timestamp").IsConcurrencyToken();
-
- modelBuilder.Entity()
- .ToTable("Rating")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Value)
- .IsRequired()
- .HasField("_Value")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Votes)
- .HasField("_Votes")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasOne(x => x.RatingType)
- .WithOne()
- .HasForeignKey("RatingSource_RatingType_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("RatingType")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(1024)
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.MaximumValue)
- .IsRequired()
- .HasField("_MaximumValue")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.MinimumValue)
- .IsRequired()
- .HasField("_MinimumValue")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity()
- .Property(t => t.Timestamp)
- .IsRequired()
- .HasField("_Timestamp")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .IsRowVersion();
- modelBuilder.Entity()
- .HasOne(x => x.Source)
- .WithOne()
- .HasForeignKey("MetadataProviderId_Source_Id")
- .IsRequired();
-
- modelBuilder.Entity()
- .ToTable("Release")
- .HasKey(t => t.Id);
- modelBuilder.Entity()
- .Property(t => t.Id)
- .IsRequired()
- .HasField("_Id")
- .UsePropertyAccessMode(PropertyAccessMode.Property)
- .ValueGeneratedOnAdd();
- modelBuilder.Entity()
- .Property(t => t.Name)
- .HasMaxLength(1024)
- .IsRequired()
- .HasField("_Name")
- .UsePropertyAccessMode(PropertyAccessMode.Property);
- modelBuilder.Entity