Merge branch 'master' of github.com:jellyfin/jellyfin into nfo-watched
This commit is contained in:
commit
ab5fb1b1f2
|
@ -7,7 +7,7 @@ parameters:
|
||||||
default: "ubuntu-latest"
|
default: "ubuntu-latest"
|
||||||
- name: DotNetSdkVersion
|
- name: DotNetSdkVersion
|
||||||
type: string
|
type: string
|
||||||
default: 5.0.100
|
default: 5.0.103
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job: CompatibilityCheck
|
- job: CompatibilityCheck
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
default: "ubuntu-latest"
|
default: "ubuntu-latest"
|
||||||
- name: GeneratorVersion
|
- name: GeneratorVersion
|
||||||
type: string
|
type: string
|
||||||
default: "5.0.0-beta2"
|
default: "5.0.1"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job: GenerateApiClients
|
- job: GenerateApiClients
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
parameters:
|
parameters:
|
||||||
LinuxImage: 'ubuntu-latest'
|
LinuxImage: 'ubuntu-latest'
|
||||||
RestoreBuildProjects: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
RestoreBuildProjects: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
||||||
DotNetSdkVersion: 5.0.100
|
DotNetSdkVersion: 5.0.103
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job: Build
|
- job: Build
|
||||||
|
|
|
@ -10,7 +10,7 @@ parameters:
|
||||||
default: "tests/**/*Tests.csproj"
|
default: "tests/**/*Tests.csproj"
|
||||||
- name: DotNetSdkVersion
|
- name: DotNetSdkVersion
|
||||||
type: string
|
type: string
|
||||||
default: 5.0.100
|
default: 5.0.103
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
- job: Test
|
- job: Test
|
||||||
|
|
|
@ -6,7 +6,7 @@ variables:
|
||||||
- name: RestoreBuildProjects
|
- name: RestoreBuildProjects
|
||||||
value: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
value: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
||||||
- name: DotNetSdkVersion
|
- name: DotNetSdkVersion
|
||||||
value: 5.0.100
|
value: 5.0.103
|
||||||
|
|
||||||
pr:
|
pr:
|
||||||
autoCancel: true
|
autoCancel: true
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
||||||
|
|
||||||
Identification = new DeviceIdentification
|
Identification = new DeviceIdentification
|
||||||
{
|
{
|
||||||
FriendlyName = @"KDL-\d{2}[EHLNPB]X\d[01]\d.*",
|
FriendlyName = @"KDL-[0-9]{2}[EHLNPB]X[0-9][01][0-9].*",
|
||||||
Manufacturer = "Sony",
|
Manufacturer = "Sony",
|
||||||
|
|
||||||
Headers = new[]
|
Headers = new[]
|
||||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
||||||
new HttpHeaderInfo
|
new HttpHeaderInfo
|
||||||
{
|
{
|
||||||
Name = "X-AV-Client-Info",
|
Name = "X-AV-Client-Info",
|
||||||
Value = @".*KDL-\d{2}[EHLNPB]X\d[01]\d.*",
|
Value = @".*KDL-[0-9]{2}[EHLNPB]X[0-9][01][0-9].*",
|
||||||
Match = HeaderMatchType.Regex
|
Match = HeaderMatchType.Regex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
||||||
|
|
||||||
Identification = new DeviceIdentification
|
Identification = new DeviceIdentification
|
||||||
{
|
{
|
||||||
FriendlyName = @"KDL-\d{2}([A-Z]X\d2\d|CX400).*",
|
FriendlyName = @"KDL-[0-9]{2}([A-Z]X[0-9]2[0-9]|CX400).*",
|
||||||
Manufacturer = "Sony",
|
Manufacturer = "Sony",
|
||||||
|
|
||||||
Headers = new[]
|
Headers = new[]
|
||||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
||||||
new HttpHeaderInfo
|
new HttpHeaderInfo
|
||||||
{
|
{
|
||||||
Name = "X-AV-Client-Info",
|
Name = "X-AV-Client-Info",
|
||||||
Value = @".*KDL-\d{2}([A-Z]X\d2\d|CX400).*",
|
Value = @".*KDL-[0-9]{2}([A-Z]X[0-9]2[0-9]|CX400).*",
|
||||||
Match = HeaderMatchType.Regex
|
Match = HeaderMatchType.Regex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
||||||
|
|
||||||
Identification = new DeviceIdentification
|
Identification = new DeviceIdentification
|
||||||
{
|
{
|
||||||
FriendlyName = @"KDL-\d{2}[A-Z]X\d5(\d|G).*",
|
FriendlyName = @"KDL-[0-9]{2}[A-Z]X[0-9]5([0-9]|G).*",
|
||||||
Manufacturer = "Sony",
|
Manufacturer = "Sony",
|
||||||
|
|
||||||
Headers = new[]
|
Headers = new[]
|
||||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
||||||
new HttpHeaderInfo
|
new HttpHeaderInfo
|
||||||
{
|
{
|
||||||
Name = "X-AV-Client-Info",
|
Name = "X-AV-Client-Info",
|
||||||
Value = @".*KDL-\d{2}[A-Z]X\d5(\d|G).*",
|
Value = @".*KDL-[0-9]{2}[A-Z]X[0-9]5([0-9]|G).*",
|
||||||
Match = HeaderMatchType.Regex
|
Match = HeaderMatchType.Regex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
||||||
|
|
||||||
Identification = new DeviceIdentification
|
Identification = new DeviceIdentification
|
||||||
{
|
{
|
||||||
FriendlyName = @"KDL-\d{2}[WR][5689]\d{2}A.*",
|
FriendlyName = @"KDL-[0-9]{2}[WR][5689][0-9]{2}A.*",
|
||||||
Manufacturer = "Sony",
|
Manufacturer = "Sony",
|
||||||
|
|
||||||
Headers = new[]
|
Headers = new[]
|
||||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
||||||
new HttpHeaderInfo
|
new HttpHeaderInfo
|
||||||
{
|
{
|
||||||
Name = "X-AV-Client-Info",
|
Name = "X-AV-Client-Info",
|
||||||
Value = @".*KDL-\d{2}[WR][5689]\d{2}A.*",
|
Value = @".*KDL-[0-9]{2}[WR][5689][0-9]{2}A.*",
|
||||||
Match = HeaderMatchType.Regex
|
Match = HeaderMatchType.Regex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
||||||
|
|
||||||
Identification = new DeviceIdentification
|
Identification = new DeviceIdentification
|
||||||
{
|
{
|
||||||
FriendlyName = @"(KDL-\d{2}W[5-9]\d{2}B|KDL-\d{2}R480|XBR-\d{2}X[89]\d{2}B|KD-\d{2}[SX][89]\d{3}B).*",
|
FriendlyName = @"(KDL-[0-9]{2}W[5-9][0-9]{2}B|KDL-[0-9]{2}R480|XBR-[0-9]{2}X[89][0-9]{2}B|KD-[0-9]{2}[SX][89][0-9]{3}B).*",
|
||||||
Manufacturer = "Sony",
|
Manufacturer = "Sony",
|
||||||
|
|
||||||
Headers = new[]
|
Headers = new[]
|
||||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
||||||
new HttpHeaderInfo
|
new HttpHeaderInfo
|
||||||
{
|
{
|
||||||
Name = "X-AV-Client-Info",
|
Name = "X-AV-Client-Info",
|
||||||
Value = @".*(KDL-\d{2}W[5-9]\d{2}B|KDL-\d{2}R480|XBR-\d{2}X[89]\d{2}B|KD-\d{2}[SX][89]\d{3}B).*",
|
Value = @".*(KDL-[0-9]{2}W[5-9][0-9]{2}B|KDL-[0-9]{2}R480|XBR-[0-9]{2}X[89][0-9]{2}B|KD-[0-9]{2}[SX][89][0-9]{3}B).*",
|
||||||
Match = HeaderMatchType.Regex
|
Match = HeaderMatchType.Regex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
<Name>Sony Bravia (2010)</Name>
|
<Name>Sony Bravia (2010)</Name>
|
||||||
<Identification>
|
<Identification>
|
||||||
<FriendlyName>KDL-\d{2}[EHLNPB]X\d[01]\d.*</FriendlyName>
|
<FriendlyName>KDL-[0-9]{2}[EHLNPB]X[0-9][01][0-9].*</FriendlyName>
|
||||||
<Manufacturer>Sony</Manufacturer>
|
<Manufacturer>Sony</Manufacturer>
|
||||||
<Headers>
|
<Headers>
|
||||||
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}[EHLNPB]X\d[01]\d.*" match="Regex" />
|
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-[0-9]{2}[EHLNPB]X[0-9][01][0-9].*" match="Regex" />
|
||||||
</Headers>
|
</Headers>
|
||||||
</Identification>
|
</Identification>
|
||||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
<Name>Sony Bravia (2011)</Name>
|
<Name>Sony Bravia (2011)</Name>
|
||||||
<Identification>
|
<Identification>
|
||||||
<FriendlyName>KDL-\d{2}([A-Z]X\d2\d|CX400).*</FriendlyName>
|
<FriendlyName>KDL-[0-9]{2}([A-Z]X[0-9]2[0-9]|CX400).*</FriendlyName>
|
||||||
<Manufacturer>Sony</Manufacturer>
|
<Manufacturer>Sony</Manufacturer>
|
||||||
<Headers>
|
<Headers>
|
||||||
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}([A-Z]X\d2\d|CX400).*" match="Regex" />
|
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-[0-9]{2}([A-Z]X[0-9]2[0-9]|CX400).*" match="Regex" />
|
||||||
</Headers>
|
</Headers>
|
||||||
</Identification>
|
</Identification>
|
||||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
<Name>Sony Bravia (2012)</Name>
|
<Name>Sony Bravia (2012)</Name>
|
||||||
<Identification>
|
<Identification>
|
||||||
<FriendlyName>KDL-\d{2}[A-Z]X\d5(\d|G).*</FriendlyName>
|
<FriendlyName>KDL-[0-9]{2}[A-Z]X[0-9]5([0-9]|G).*</FriendlyName>
|
||||||
<Manufacturer>Sony</Manufacturer>
|
<Manufacturer>Sony</Manufacturer>
|
||||||
<Headers>
|
<Headers>
|
||||||
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}[A-Z]X\d5(\d|G).*" match="Regex" />
|
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-[0-9]{2}[A-Z]X[0-9]5([0-9]|G).*" match="Regex" />
|
||||||
</Headers>
|
</Headers>
|
||||||
</Identification>
|
</Identification>
|
||||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
<Name>Sony Bravia (2013)</Name>
|
<Name>Sony Bravia (2013)</Name>
|
||||||
<Identification>
|
<Identification>
|
||||||
<FriendlyName>KDL-\d{2}[WR][5689]\d{2}A.*</FriendlyName>
|
<FriendlyName>KDL-[0-9]{2}[WR][5689][0-9]{2}A.*</FriendlyName>
|
||||||
<Manufacturer>Sony</Manufacturer>
|
<Manufacturer>Sony</Manufacturer>
|
||||||
<Headers>
|
<Headers>
|
||||||
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-\d{2}[WR][5689]\d{2}A.*" match="Regex" />
|
<HttpHeaderInfo name="X-AV-Client-Info" value=".*KDL-[0-9]{2}[WR][5689][0-9]{2}A.*" match="Regex" />
|
||||||
</Headers>
|
</Headers>
|
||||||
</Identification>
|
</Identification>
|
||||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||||
<Name>Sony Bravia (2014)</Name>
|
<Name>Sony Bravia (2014)</Name>
|
||||||
<Identification>
|
<Identification>
|
||||||
<FriendlyName>(KDL-\d{2}W[5-9]\d{2}B|KDL-\d{2}R480|XBR-\d{2}X[89]\d{2}B|KD-\d{2}[SX][89]\d{3}B).*</FriendlyName>
|
<FriendlyName>(KDL-[0-9]{2}W[5-9][0-9]{2}B|KDL-[0-9]{2}R480|XBR-[0-9]{2}X[89][0-9]{2}B|KD-[0-9]{2}[SX][89][0-9]{3}B).*</FriendlyName>
|
||||||
<Manufacturer>Sony</Manufacturer>
|
<Manufacturer>Sony</Manufacturer>
|
||||||
<Headers>
|
<Headers>
|
||||||
<HttpHeaderInfo name="X-AV-Client-Info" value=".*(KDL-\d{2}W[5-9]\d{2}B|KDL-\d{2}R480|XBR-\d{2}X[89]\d{2}B|KD-\d{2}[SX][89]\d{3}B).*" match="Regex" />
|
<HttpHeaderInfo name="X-AV-Client-Info" value=".*(KDL-[0-9]{2}W[5-9][0-9]{2}B|KDL-[0-9]{2}R480|XBR-[0-9]{2}X[89][0-9]{2}B|KD-[0-9]{2}[SX][89][0-9]{3}B).*" match="Regex" />
|
||||||
</Headers>
|
</Headers>
|
||||||
</Identification>
|
</Identification>
|
||||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||||
|
|
|
@ -284,7 +284,7 @@ namespace Emby.Naming.Common
|
||||||
|
|
||||||
// Not a Kodi rule as well, but below rule also causes false positives for triple-digit episode names
|
// Not a Kodi rule as well, but below rule also causes false positives for triple-digit episode names
|
||||||
// [bar] Foo - 1 [baz] special case of below expression to prevent false positives with digits in the series name
|
// [bar] Foo - 1 [baz] special case of below expression to prevent false positives with digits in the series name
|
||||||
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[\s_]*-[\s_]*(?<epnumber>\d+).*$")
|
new EpisodeExpression(@".*?(\[.*?\])+.*?(?<seriesname>[\w\s]+?)[\s_]*-[\s_]*(?<epnumber>[0-9]+).*$")
|
||||||
{
|
{
|
||||||
IsNamed = true
|
IsNamed = true
|
||||||
},
|
},
|
||||||
|
@ -588,7 +588,7 @@ namespace Emby.Naming.Common
|
||||||
AudioBookNamesExpressions = new[]
|
AudioBookNamesExpressions = new[]
|
||||||
{
|
{
|
||||||
// Detect year usually in brackets after name Batman (2020)
|
// Detect year usually in brackets after name Batman (2020)
|
||||||
@"^(?<name>.+?)\s*\(\s*(?<year>\d{4})\s*\)\s*$",
|
@"^(?<name>.+?)\s*\(\s*(?<year>[0-9]{4})\s*\)\s*$",
|
||||||
@"^\s*(?<name>[^ ].*?)\s*$"
|
@"^\s*(?<name>[^ ].*?)\s*$"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Naming</PackageId>
|
<PackageId>Jellyfin.Naming</PackageId>
|
||||||
<VersionPrefix>10.7.0</VersionPrefix>
|
<VersionPrefix>10.8.0</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Buffers;
|
||||||
using System.IO.Pipelines;
|
using System.IO.Pipelines;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -138,7 +139,7 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
writer.Advance(bytesRead);
|
writer.Advance(bytesRead);
|
||||||
|
|
||||||
// Make the data available to the PipeReader
|
// Make the data available to the PipeReader
|
||||||
FlushResult flushResult = await writer.FlushAsync().ConfigureAwait(false);
|
FlushResult flushResult = await writer.FlushAsync(cancellationToken).ConfigureAwait(false);
|
||||||
if (flushResult.IsCompleted)
|
if (flushResult.IsCompleted)
|
||||||
{
|
{
|
||||||
// The PipeReader stopped reading
|
// The PipeReader stopped reading
|
||||||
|
@ -181,32 +182,16 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
|
|
||||||
WebSocketMessage<object>? stub;
|
WebSocketMessage<object>? stub;
|
||||||
|
long bytesConsumed = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
stub = DeserializeWebSocketMessage(buffer, out bytesConsumed);
|
||||||
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)
|
catch (JsonException ex)
|
||||||
{
|
{
|
||||||
// Tell the PipeReader how much of the buffer we have consumed
|
// Tell the PipeReader how much of the buffer we have consumed
|
||||||
reader.AdvanceTo(buffer.End);
|
reader.AdvanceTo(buffer.End);
|
||||||
_logger.LogError(ex, "Error processing web socket message");
|
_logger.LogError(ex, "Error processing web socket message: {Data}", Encoding.UTF8.GetString(buffer));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,27 +202,34 @@ namespace Emby.Server.Implementations.HttpServer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell the PipeReader how much of the buffer we have consumed
|
// Tell the PipeReader how much of the buffer we have consumed
|
||||||
reader.AdvanceTo(buffer.End);
|
reader.AdvanceTo(buffer.GetPosition(bytesConsumed));
|
||||||
|
|
||||||
_logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub);
|
_logger.LogDebug("WS {IP} received message: {@Message}", RemoteEndPoint, stub);
|
||||||
|
|
||||||
var info = new WebSocketMessageInfo
|
if (stub.MessageType == SessionMessageType.KeepAlive)
|
||||||
{
|
|
||||||
MessageType = stub.MessageType,
|
|
||||||
Data = stub.Data?.ToString(), // Data can be null
|
|
||||||
Connection = this
|
|
||||||
};
|
|
||||||
|
|
||||||
if (info.MessageType == SessionMessageType.KeepAlive)
|
|
||||||
{
|
{
|
||||||
await SendKeepAliveResponse().ConfigureAwait(false);
|
await SendKeepAliveResponse().ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await OnReceive(info).ConfigureAwait(false);
|
await OnReceive(
|
||||||
|
new WebSocketMessageInfo
|
||||||
|
{
|
||||||
|
MessageType = stub.MessageType,
|
||||||
|
Data = stub.Data?.ToString(), // Data can be null
|
||||||
|
Connection = this
|
||||||
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal WebSocketMessage<object>? DeserializeWebSocketMessage(ReadOnlySequence<byte> bytes, out long bytesConsumed)
|
||||||
|
{
|
||||||
|
var jsonReader = new Utf8JsonReader(bytes);
|
||||||
|
var ret = JsonSerializer.Deserialize<WebSocketMessage<object>>(ref jsonReader, _jsonOptions);
|
||||||
|
bytesConsumed = jsonReader.BytesConsumed;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
private Task SendKeepAliveResponse()
|
private Task SendKeepAliveResponse()
|
||||||
{
|
{
|
||||||
LastKeepAliveDate = DateTime.UtcNow;
|
LastKeepAliveDate = DateTime.UtcNow;
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||||
public LegacyHdHomerunChannelCommands(string url)
|
public LegacyHdHomerunChannelCommands(string url)
|
||||||
{
|
{
|
||||||
// parse url for channel and program
|
// parse url for channel and program
|
||||||
var regExp = new Regex(@"\/ch(\d+)-?(\d*)");
|
var regExp = new Regex(@"\/ch([0-9]+)-?([0-9]*)");
|
||||||
var match = regExp.Match(url);
|
var match = regExp.Match(url);
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
|
|
26
Emby.Server.Implementations/Localization/Core/eo.json
Normal file
26
Emby.Server.Implementations/Localization/Core/eo.json
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"NotificationOptionInstallationFailed": "Instalada fiasko",
|
||||||
|
"NotificationOptionAudioPlaybackStopped": "Sono de ludado haltis",
|
||||||
|
"NotificationOptionAudioPlayback": "Ludado de sono startis",
|
||||||
|
"NameSeasonUnknown": "Sezono Nekonata",
|
||||||
|
"NameSeasonNumber": "Sezono {0}",
|
||||||
|
"NameInstallFailed": "{0} instalado fiaskis",
|
||||||
|
"Music": "Muziko",
|
||||||
|
"Movies": "Filmoj",
|
||||||
|
"ItemRemovedWithName": "{0} forigis el la biblioteko",
|
||||||
|
"ItemAddedWithName": "{0} aldonis al la biblioteko",
|
||||||
|
"HeaderLiveTV": "Viva Televido",
|
||||||
|
"HeaderContinueWatching": "Daŭrigi Spektado",
|
||||||
|
"HeaderAlbumArtists": "Artistoj de Albumo",
|
||||||
|
"Folders": "Dosierujoj",
|
||||||
|
"DeviceOnlineWithName": "{0} estas konektita",
|
||||||
|
"Default": "Defaŭlte",
|
||||||
|
"Collections": "Kolektoj",
|
||||||
|
"ChapterNameValue": "Ĉapitro {0}",
|
||||||
|
"Channels": "Kanaloj",
|
||||||
|
"Books": "Libroj",
|
||||||
|
"Artists": "Artistoj",
|
||||||
|
"Application": "Aplikaĵo",
|
||||||
|
"AppDeviceValues": "Aplikaĵo: {0}, Aparato: {1}",
|
||||||
|
"Albums": "Albumoj"
|
||||||
|
}
|
|
@ -1,121 +1,121 @@
|
||||||
{
|
{
|
||||||
"HeaderLiveTV": "Live-TV",
|
"HeaderLiveTV": "Live TV",
|
||||||
"NewVersionIsAvailable": "Uusi versio Jellyfin palvelimesta on ladattavissa.",
|
"NewVersionIsAvailable": "Uusi versio Jellyfin-palvelimesta on ladattavissa.",
|
||||||
"NameSeasonUnknown": "Tuntematon kausi",
|
"NameSeasonUnknown": "Tuntematon kausi",
|
||||||
"NameSeasonNumber": "Kausi {0}",
|
"NameSeasonNumber": "Kausi {0}",
|
||||||
"NameInstallFailed": "{0} asennus epäonnistui",
|
"NameInstallFailed": "{0} asennus epäonnistui",
|
||||||
"MusicVideos": "Musiikkivideot",
|
"MusicVideos": "Musiikkivideot",
|
||||||
"Music": "Musiikki",
|
"Music": "Musiikki",
|
||||||
"Movies": "Elokuvat",
|
"Movies": "Elokuvat",
|
||||||
"MixedContent": "Sekoitettu sisältö",
|
"MixedContent": "Sekalainen sisältö",
|
||||||
"MessageServerConfigurationUpdated": "Palvelimen asetukset on päivitetty",
|
"MessageServerConfigurationUpdated": "Palvelimen asetukset on päivitetty",
|
||||||
"MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen asetusryhmä {0} on päivitetty",
|
"MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen asetusten osio {0} on päivitetty",
|
||||||
"MessageApplicationUpdatedTo": "Jellyfin palvelin on päivitetty versioon {0}",
|
"MessageApplicationUpdatedTo": "Jellyfin-palvelin on päivitetty versioon {0}",
|
||||||
"MessageApplicationUpdated": "Jellyfin palvelin on päivitetty",
|
"MessageApplicationUpdated": "Jellyfin-palvelin on päivitetty",
|
||||||
"Latest": "Uusimmat",
|
"Latest": "Viimeisimmät",
|
||||||
"LabelRunningTimeValue": "Toiston kesto: {0}",
|
"LabelRunningTimeValue": "Kesto: {0}",
|
||||||
"LabelIpAddressValue": "IP-osoite: {0}",
|
"LabelIpAddressValue": "IP-osoite: {0}",
|
||||||
"ItemRemovedWithName": "{0} poistettiin kirjastosta",
|
"ItemRemovedWithName": "{0} poistettiin kirjastosta",
|
||||||
"ItemAddedWithName": "{0} lisättiin kirjastoon",
|
"ItemAddedWithName": "{0} lisättiin kirjastoon",
|
||||||
"Inherit": "Periytyä",
|
"Inherit": "Peri",
|
||||||
"HomeVideos": "Kotivideot",
|
"HomeVideos": "Kotivideot",
|
||||||
"HeaderRecordingGroups": "Tallennusryhmät",
|
"HeaderRecordingGroups": "Tallennusryhmät",
|
||||||
"HeaderNextUp": "Seuraavaksi",
|
"HeaderNextUp": "Seuraavaksi",
|
||||||
"HeaderFavoriteSongs": "Suosikkikappaleet",
|
"HeaderFavoriteSongs": "Suosikkikappaleet",
|
||||||
"HeaderFavoriteShows": "Suosikkisarjat",
|
"HeaderFavoriteShows": "Suosikkisarjat",
|
||||||
"HeaderFavoriteEpisodes": "Suosikkijaksot",
|
"HeaderFavoriteEpisodes": "Suosikkijaksot",
|
||||||
"HeaderFavoriteArtists": "Suosikkiartistit",
|
"HeaderFavoriteArtists": "Suosikkiesittäjät",
|
||||||
"HeaderFavoriteAlbums": "Suosikkialbumit",
|
"HeaderFavoriteAlbums": "Suosikkialbumit",
|
||||||
"HeaderContinueWatching": "Jatka katsomista",
|
"HeaderContinueWatching": "Jatka katselua",
|
||||||
"HeaderAlbumArtists": "Albumin artistit",
|
"HeaderAlbumArtists": "Albumin esittäjät",
|
||||||
"Genres": "Tyylilajit",
|
"Genres": "Tyylilajit",
|
||||||
"Folders": "Kansiot",
|
"Folders": "Kansiot",
|
||||||
"Favorites": "Suosikit",
|
"Favorites": "Suosikit",
|
||||||
"FailedLoginAttemptWithUserName": "Kirjautuminen epäonnistui kohteesta {0}",
|
"FailedLoginAttemptWithUserName": "Epäonnistunut kirjautumisyritys lähteestä \"{0}\"",
|
||||||
"DeviceOnlineWithName": "{0} on yhdistetty",
|
"DeviceOnlineWithName": "{0} on yhdistetty",
|
||||||
"DeviceOfflineWithName": "{0} yhteys on katkaistu",
|
"DeviceOfflineWithName": "{0} on katkaissut yhteyden",
|
||||||
"Collections": "Kokoelmat",
|
"Collections": "Kokoelmat",
|
||||||
"ChapterNameValue": "Jakso: {0}",
|
"ChapterNameValue": "Kappale {0}",
|
||||||
"Channels": "Kanavat",
|
"Channels": "Kanavat",
|
||||||
"CameraImageUploadedFrom": "Uusi kamerakuva on ladattu {0}",
|
"CameraImageUploadedFrom": "Uusi kameran kuva on sirretty lähteestä {0}",
|
||||||
"Books": "Kirjat",
|
"Books": "Kirjat",
|
||||||
"AuthenticationSucceededWithUserName": "Käyttäjän {0} todennus onnistui",
|
"AuthenticationSucceededWithUserName": "{0} on todennettu",
|
||||||
"Artists": "Artistit",
|
"Artists": "Esittäjät",
|
||||||
"Application": "Sovellus",
|
"Application": "Sovellus",
|
||||||
"AppDeviceValues": "Sovellus: {0}, Laite: {1}",
|
"AppDeviceValues": "Sovellus: {0}, Laite: {1}",
|
||||||
"Albums": "Albumit",
|
"Albums": "Albumit",
|
||||||
"User": "Käyttäjä",
|
"User": "Käyttäjä",
|
||||||
"System": "Järjestelmä",
|
"System": "Järjestelmä",
|
||||||
"ScheduledTaskFailedWithName": "{0} epäonnistui",
|
"ScheduledTaskFailedWithName": "{0} epäonnistui",
|
||||||
"PluginUpdatedWithName": "{0} päivitetty",
|
"PluginUpdatedWithName": "{0} päivitettiin",
|
||||||
"PluginInstalledWithName": "{0} asennettu",
|
"PluginInstalledWithName": "{0} asennettiin",
|
||||||
"Photos": "Kuvat",
|
"Photos": "Valokuvat",
|
||||||
"ScheduledTaskStartedWithName": "{0} aloitettu",
|
"ScheduledTaskStartedWithName": "\"{0}\" käynnistetty",
|
||||||
"PluginUninstalledWithName": "{0} poistettu",
|
"PluginUninstalledWithName": "{0} poistettiin",
|
||||||
"Playlists": "Soittolistat",
|
"Playlists": "Soittolistat",
|
||||||
"VersionNumber": "Versio {0}",
|
"VersionNumber": "Versio {0}",
|
||||||
"ValueSpecialEpisodeName": "Erikois - {0}",
|
"ValueSpecialEpisodeName": "Erikoisjakso - {0}",
|
||||||
"ValueHasBeenAddedToLibrary": "{0} lisättiin mediakirjastoon",
|
"ValueHasBeenAddedToLibrary": "\"{0}\" on lisätty mediakirjastoon",
|
||||||
"UserStoppedPlayingItemWithValues": "{0} toistaminen valmistui {1} laitteella {2}",
|
"UserStoppedPlayingItemWithValues": "{0} lopetti kohteen \"{1}\" toiston sijainnissa \"{2}\"",
|
||||||
"UserStartedPlayingItemWithValues": "{0} toistaa {1} laitteella {2}",
|
"UserStartedPlayingItemWithValues": "{0} toistaa kohdetta \"{1}\" sijainnissa \"{2}\"",
|
||||||
"UserPolicyUpdatedWithName": "Käyttöoikeudet päivitetty käyttäjälle {0}",
|
"UserPolicyUpdatedWithName": "Käyttäjän {0} käyttöoikeudet on päivitetty",
|
||||||
"UserPasswordChangedWithName": "Salasana vaihdettu käyttäjälle {0}",
|
"UserPasswordChangedWithName": "Käyttäjän {0} salasana on vaihdettu",
|
||||||
"UserOnlineFromDevice": "{0} on paikalla osoitteesta {1}",
|
"UserOnlineFromDevice": "{0} on yhdistänyt sijainnista \"{1}\"",
|
||||||
"UserOfflineFromDevice": "{0} yhteys katkaistu kohteesta {1}",
|
"UserOfflineFromDevice": "{0} on katkaissut yhteyden sijainnista \"{1}\"",
|
||||||
"UserLockedOutWithName": "Käyttäjä {0} lukittu",
|
"UserLockedOutWithName": "Käyttäjä {0} on lukittu",
|
||||||
"UserDownloadingItemWithValues": "{0} lataa {1}",
|
"UserDownloadingItemWithValues": "{0} lataa kohdetta \"{1}\"",
|
||||||
"UserDeletedWithName": "Käyttäjä {0} poistettu",
|
"UserDeletedWithName": "Käyttäjä {0} on poistettu",
|
||||||
"UserCreatedWithName": "Käyttäjä {0} luotu",
|
"UserCreatedWithName": "Käyttäjä {0} on luotu",
|
||||||
"TvShows": "TV-ohjelmat",
|
"TvShows": "Sarjat",
|
||||||
"Sync": "Synkronoi",
|
"Sync": "Synkronointi",
|
||||||
"SubtitleDownloadFailureFromForItem": "Tekstitystä ei voitu ladata osoitteesta {0} kohteelle {1}",
|
"SubtitleDownloadFailureFromForItem": "Tekstityksen lataus lähteestä \"{0}\" kohteelle \"{1}\" epäonnistui",
|
||||||
"StartupEmbyServerIsLoading": "Jellyfin palvelin latautuu. Yritä hetken kuluttua uudelleen.",
|
"StartupEmbyServerIsLoading": "Jellyfin-palvelin latautuu. Yritä hetken kuluttua uudelleen.",
|
||||||
"Songs": "Kappaleet",
|
"Songs": "Kappaleet",
|
||||||
"Shows": "Ohjelmat",
|
"Shows": "Sarjat",
|
||||||
"ServerNameNeedsToBeRestarted": "{0} on käynnistettävä uudelleen",
|
"ServerNameNeedsToBeRestarted": "\"{0}\" on käynnistettävä uudelleen",
|
||||||
"ProviderValue": "Tarjoaja: {0}",
|
"ProviderValue": "Lähde: {0}",
|
||||||
"Plugin": "Liitännäinen",
|
"Plugin": "Laajennus",
|
||||||
"NotificationOptionVideoPlaybackStopped": "Videon toisto pysäytetty",
|
"NotificationOptionVideoPlaybackStopped": "Videon toisto lopetettu",
|
||||||
"NotificationOptionVideoPlayback": "Videota toistetaan",
|
"NotificationOptionVideoPlayback": "Videon toisto aloitettu",
|
||||||
"NotificationOptionUserLockedOut": "Käyttäjä kirjautui ulos",
|
"NotificationOptionUserLockedOut": "Käyttäjä on lukittu",
|
||||||
"NotificationOptionTaskFailed": "Ajastettu tehtävä epäonnistui",
|
"NotificationOptionTaskFailed": "Ajoitettu tehtävä epäonnistui",
|
||||||
"NotificationOptionServerRestartRequired": "Palvelin on käynnistettävä uudelleen",
|
"NotificationOptionServerRestartRequired": "Tarvitaan palvelimen uudelleenkäynnistys",
|
||||||
"NotificationOptionPluginUpdateInstalled": "Liitännäinen päivitetty",
|
"NotificationOptionPluginUpdateInstalled": "Laajennus on päivitetty",
|
||||||
"NotificationOptionPluginUninstalled": "Liitännäinen poistettu",
|
"NotificationOptionPluginUninstalled": "Laajennus on poistettu",
|
||||||
"NotificationOptionPluginInstalled": "Liitännäinen asennettu",
|
"NotificationOptionPluginInstalled": "Laajennus on asennettu",
|
||||||
"NotificationOptionPluginError": "Ongelma liitännäisessä",
|
"NotificationOptionPluginError": "Laajennuksen virhe",
|
||||||
"NotificationOptionNewLibraryContent": "Uutta sisältöä lisätty",
|
"NotificationOptionNewLibraryContent": "Sisältöä on lisätty",
|
||||||
"NotificationOptionInstallationFailed": "Asennus epäonnistui",
|
"NotificationOptionInstallationFailed": "Asennus epäonnistui",
|
||||||
"NotificationOptionCameraImageUploaded": "Kameran kuva ladattu",
|
"NotificationOptionCameraImageUploaded": "Kameran kuva on tallennettu",
|
||||||
"NotificationOptionAudioPlaybackStopped": "Äänen toisto lopetettu",
|
"NotificationOptionAudioPlaybackStopped": "Äänen toisto lopetettu",
|
||||||
"NotificationOptionAudioPlayback": "Toistetaan ääntä",
|
"NotificationOptionAudioPlayback": "Äänen toisto aloitettu",
|
||||||
"NotificationOptionApplicationUpdateInstalled": "Sovelluspäivitys asennettu",
|
"NotificationOptionApplicationUpdateInstalled": "Sovelluspäivitys asennettiin",
|
||||||
"NotificationOptionApplicationUpdateAvailable": "Ohjelmistopäivitys saatavilla",
|
"NotificationOptionApplicationUpdateAvailable": "Sovelluspäivitys on saatavilla",
|
||||||
"TasksMaintenanceCategory": "Ylläpito",
|
"TasksMaintenanceCategory": "Ylläpito",
|
||||||
"TaskDownloadMissingSubtitlesDescription": "Etsii puuttuvia tekstityksiä videon metadatatietojen pohjalta.",
|
"TaskDownloadMissingSubtitlesDescription": "Etsii puuttuvia tekstityksiä määritettyjen metatietoasetusten mukaisesti.",
|
||||||
"TaskDownloadMissingSubtitles": "Lataa puuttuvat tekstitykset",
|
"TaskDownloadMissingSubtitles": "Lataa puuttuvat tekstitykset",
|
||||||
"TaskRefreshChannelsDescription": "Päivittää internet-kanavien tiedot.",
|
"TaskRefreshChannelsDescription": "Päivittää internet-kanavien tiedot.",
|
||||||
"TaskRefreshChannels": "Päivitä kanavat",
|
"TaskRefreshChannels": "Päivitä kanavat",
|
||||||
"TaskCleanTranscodeDescription": "Poistaa transkoodatut tiedostot jotka ovat yli päivän vanhoja.",
|
"TaskCleanTranscodeDescription": "Poistaa päivää vanhemmat transkoodaustiedostot.",
|
||||||
"TaskCleanTranscode": "Puhdista transkoodaushakemisto",
|
"TaskCleanTranscode": "Puhdista transkoodauskansio",
|
||||||
"TaskUpdatePluginsDescription": "Lataa ja asentaa päivitykset liitännäisille jotka on asetettu päivittymään automaattisesti.",
|
"TaskUpdatePluginsDescription": "Lataa ja asentaa päivitykset laajennuksille, jotka on määritetty päivittymään automaattisesti.",
|
||||||
"TaskUpdatePlugins": "Päivitä liitännäiset",
|
"TaskUpdatePlugins": "Päivitä laajennukset",
|
||||||
"TaskRefreshPeopleDescription": "Päivittää näyttelijöiden ja ohjaajien mediatiedot kirjastossasi.",
|
"TaskRefreshPeopleDescription": "Päivittää mediakirjaston näyttelijöiden ja ohjaajien metatiedot.",
|
||||||
"TaskRefreshPeople": "Päivitä henkilöt",
|
"TaskRefreshPeople": "Päivitä henkilöt",
|
||||||
"TaskCleanLogsDescription": "Poistaa lokitiedostot jotka ovat yli {0} päivää vanhoja.",
|
"TaskCleanLogsDescription": "Poistaa {0} päivää vanhemmat lokitiedostot.",
|
||||||
"TaskCleanLogs": "Puhdista lokihakemisto",
|
"TaskCleanLogs": "Siivoa lokikansio",
|
||||||
"TaskRefreshLibraryDescription": "Skannaa mediakirjastosi uudet tiedostot ja päivittää metatiedot.",
|
"TaskRefreshLibraryDescription": "Tarkastaa mediakirjastosi sisällön uusien tiedostojen varalta ja päivittää metatiedot.",
|
||||||
"TaskRefreshLibrary": "Skannaa mediakirjasto",
|
"TaskRefreshLibrary": "Päivitä mediakirjasto",
|
||||||
"TaskRefreshChapterImagesDescription": "Luo pienoiskuvat videoille joissa on jaksoja.",
|
"TaskRefreshChapterImagesDescription": "Luo esikatselukuvat videoille, jotka sisältävät kappalejaon.",
|
||||||
"TaskRefreshChapterImages": "Pura jakson kuvat",
|
"TaskRefreshChapterImages": "Pura kappalejaon kuvat",
|
||||||
"TaskCleanCacheDescription": "Poistaa järjestelmälle tarpeettomat väliaikaistiedostot.",
|
"TaskCleanCacheDescription": "Poistaa tarpeettomiksi jääneet väliaikaistiedostot.",
|
||||||
"TaskCleanCache": "Tyhjennä välimuisti-hakemisto",
|
"TaskCleanCache": "Tyhjennä välimuistikansio",
|
||||||
"TasksChannelsCategory": "Internet kanavat",
|
"TasksChannelsCategory": "Internet-kanavat",
|
||||||
"TasksApplicationCategory": "Sovellus",
|
"TasksApplicationCategory": "Sovellus",
|
||||||
"TasksLibraryCategory": "Kirjasto",
|
"TasksLibraryCategory": "Kirjasto",
|
||||||
"Forced": "Pakotettu",
|
"Forced": "Pakotettu",
|
||||||
"Default": "Oletus",
|
"Default": "Oletus",
|
||||||
"TaskCleanActivityLogDescription": "Poistaa määritettyä vanhemmat tapahtumat aktiviteettilokista.",
|
"TaskCleanActivityLogDescription": "Poistaa määritettyä ikää vanhemmat tapahtumat toimintahistoriasta.",
|
||||||
"TaskCleanActivityLog": "Tyhjennä aktiviteettiloki",
|
"TaskCleanActivityLog": "Tyhjennä toimintahistoria",
|
||||||
"Undefined": "Määrittelemätön"
|
"Undefined": "Määrittelemätön"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"Albums": "संग्रह",
|
"Albums": "एल्बम",
|
||||||
"HeaderRecordingGroups": "रिकॉर्डिंग समूह",
|
"HeaderRecordingGroups": "रिकॉर्डिंग समूह",
|
||||||
"HeaderNextUp": "इसके बाद",
|
"HeaderNextUp": "इसके बाद",
|
||||||
"HeaderLiveTV": "लाइव टीवी",
|
"HeaderLiveTV": "लाइव टीवी",
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
"AuthenticationSucceededWithUserName": "सफलता से प्रमाणीकृत",
|
"AuthenticationSucceededWithUserName": "सफलता से प्रमाणीकृत",
|
||||||
"Artists": "कलाकारों",
|
"Artists": "कलाकारों",
|
||||||
"Application": "एप्लिकेशन",
|
"Application": "एप्लिकेशन",
|
||||||
"AppDeviceValues": "एप: {0}, मशीन: {1}",
|
"AppDeviceValues": "एप: {0}, उपकरण: {1}",
|
||||||
"NotificationOptionPluginUninstalled": "प्लगइन अनइंस्टाल हो गया",
|
"NotificationOptionPluginUninstalled": "प्लगइन अनइंस्टाल हो गया",
|
||||||
"NotificationOptionPluginInstalled": "प्लगइन इनस्टॉल हो गया",
|
"NotificationOptionPluginInstalled": "प्लगइन इनस्टॉल हो गया",
|
||||||
"NotificationOptionPluginError": "प्लगइन फ़ैल हो गया",
|
"NotificationOptionPluginError": "प्लगइन फ़ैल हो गया",
|
||||||
|
|
|
@ -348,7 +348,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var data = JsonSerializer.Serialize(manifest, _jsonOptions);
|
var data = JsonSerializer.Serialize(manifest, _jsonOptions);
|
||||||
File.WriteAllText(Path.Combine(path, "meta.json"), data, Encoding.UTF8);
|
File.WriteAllText(Path.Combine(path, "meta.json"), data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#pragma warning disable CA1031 // Do not catch general exception types
|
#pragma warning disable CA1031 // Do not catch general exception types
|
||||||
|
@ -519,7 +519,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||||
return _plugins.Remove(plugin);
|
return _plugins.Remove(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalPlugin LoadManifest(string dir)
|
internal LocalPlugin LoadManifest(string dir)
|
||||||
{
|
{
|
||||||
Version? version;
|
Version? version;
|
||||||
PluginManifest? manifest = null;
|
PluginManifest? manifest = null;
|
||||||
|
|
|
@ -1456,7 +1456,12 @@ namespace Emby.Server.Implementations.Session
|
||||||
throw new SecurityException("Unknown quick connect token");
|
throw new SecurityException("Unknown quick connect token");
|
||||||
}
|
}
|
||||||
|
|
||||||
request.UserId = result.Items[0].UserId;
|
var info = result.Items[0];
|
||||||
|
request.UserId = info.UserId;
|
||||||
|
|
||||||
|
// There's no need to keep the quick connect token in the database, as AuthenticateNewSessionInternal() issues a long lived token.
|
||||||
|
_authRepo.Delete(info);
|
||||||
|
|
||||||
return AuthenticateNewSessionInternal(request, false);
|
return AuthenticateNewSessionInternal(request, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="5.6.3" />
|
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="6.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Data</PackageId>
|
<PackageId>Jellyfin.Data</PackageId>
|
||||||
<VersionPrefix>10.7.0</VersionPrefix>
|
<VersionPrefix>10.8.0</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -41,8 +41,8 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="System.Linq.Async" Version="5.0.0" />
|
<PackageReference Include="System.Linq.Async" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.2">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.2">
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.3">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
|
@ -40,8 +40,8 @@
|
||||||
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
<PackageReference Include="CommandLineParser" Version="2.8.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.2" />
|
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.3" />
|
||||||
<PackageReference Include="prometheus-net" Version="4.1.1" />
|
<PackageReference Include="prometheus-net" Version="4.1.1" />
|
||||||
<PackageReference Include="prometheus-net.AspNetCore" Version="4.1.1" />
|
<PackageReference Include="prometheus-net.AspNetCore" Version="4.1.1" />
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Common</PackageId>
|
<PackageId>Jellyfin.Common</PackageId>
|
||||||
<VersionPrefix>10.7.0</VersionPrefix>
|
<VersionPrefix>10.8.0</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Controller</PackageId>
|
<PackageId>Jellyfin.Controller</PackageId>
|
||||||
<VersionPrefix>10.7.0</VersionPrefix>
|
<VersionPrefix>10.8.0</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -50,6 +50,14 @@ namespace MediaBrowser.Controller.MediaEncoding
|
||||||
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
|
||||||
bool SupportsHwaccel(string hwaccel);
|
bool SupportsHwaccel(string hwaccel);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether given filter is supported.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="filter">The filter.</param>
|
||||||
|
/// <param name="option">The option.</param>
|
||||||
|
/// <returns><c>true</c> if the filter is supported, <c>false</c> otherwise.</returns>
|
||||||
|
bool SupportsFilter(string filter, string option);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extracts the audio image.
|
/// Extracts the audio image.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -296,6 +296,38 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CheckFilter(string filter, string option)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(filter))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string output = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
output = GetProcessOutput(_encoderPath, "-h filter=" + filter);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error detecting the given filter");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.Contains("Filter " + filter, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(option))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return output.Contains(option, StringComparison.Ordinal);
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogWarning("Filter: {Name} with option {Option} is not available", filter, option);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private IEnumerable<string> GetCodecs(Codec codec)
|
private IEnumerable<string> GetCodecs(Codec codec)
|
||||||
{
|
{
|
||||||
string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
|
string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
|
||||||
|
|
|
@ -295,6 +295,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
||||||
return _hwaccels.Contains(hwaccel, StringComparer.OrdinalIgnoreCase);
|
return _hwaccels.Contains(hwaccel, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SupportsFilter(string filter, string option)
|
||||||
|
{
|
||||||
|
if (_ffmpegPath != null)
|
||||||
|
{
|
||||||
|
var validator = new EncoderValidator(_logger, _ffmpegPath);
|
||||||
|
return validator.CheckFilter(filter, option);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public bool CanEncodeToAudioCodec(string codec)
|
public bool CanEncodeToAudioCodec(string codec)
|
||||||
{
|
{
|
||||||
if (string.Equals(codec, "opus", StringComparison.OrdinalIgnoreCase))
|
if (string.Equals(codec, "opus", StringComparison.OrdinalIgnoreCase))
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
|
|
||||||
subEvent.Text = subEvent.Text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
|
subEvent.Text = subEvent.Text.Replace("\\n", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);
|
subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w0-9]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase);
|
||||||
|
|
||||||
trackEvents.Add(subEvent);
|
trackEvents.Add(subEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
||||||
|
|
||||||
subEvent.Text = string.Join(ParserValues.NewLine, multiline);
|
subEvent.Text = string.Join(ParserValues.NewLine, multiline);
|
||||||
subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
|
subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase);
|
||||||
subEvent.Text = Regex.Replace(subEvent.Text, @"\{(?:\\\d?[\w.-]+(?:\([^\)]*\)|&H?[0-9A-Fa-f]+&|))+\}", string.Empty, RegexOptions.IgnoreCase);
|
subEvent.Text = Regex.Replace(subEvent.Text, @"\{(?:\\[0-9]?[\w.-]+(?:\([^\)]*\)|&H?[0-9A-Fa-f]+&|))+\}", string.Empty, RegexOptions.IgnoreCase);
|
||||||
subEvent.Text = Regex.Replace(subEvent.Text, "<", "<", RegexOptions.IgnoreCase);
|
subEvent.Text = Regex.Replace(subEvent.Text, "<", "<", RegexOptions.IgnoreCase);
|
||||||
subEvent.Text = Regex.Replace(subEvent.Text, ">", ">", RegexOptions.IgnoreCase);
|
subEvent.Text = Regex.Replace(subEvent.Text, ">", ">", RegexOptions.IgnoreCase);
|
||||||
subEvent.Text = Regex.Replace(subEvent.Text, "<(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)>", "<$1$3$7>", RegexOptions.IgnoreCase);
|
subEvent.Text = Regex.Replace(subEvent.Text, "<(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)>", "<$1$3$7>", RegexOptions.IgnoreCase);
|
||||||
|
|
|
@ -39,6 +39,8 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
public bool EnableTonemapping { get; set; }
|
public bool EnableTonemapping { get; set; }
|
||||||
|
|
||||||
|
public bool EnableVppTonemapping { get; set; }
|
||||||
|
|
||||||
public string TonemappingAlgorithm { get; set; }
|
public string TonemappingAlgorithm { get; set; }
|
||||||
|
|
||||||
public string TonemappingRange { get; set; }
|
public string TonemappingRange { get; set; }
|
||||||
|
@ -65,6 +67,8 @@ namespace MediaBrowser.Model.Configuration
|
||||||
|
|
||||||
public bool EnableDecodingColorDepth10Vp9 { get; set; }
|
public bool EnableDecodingColorDepth10Vp9 { get; set; }
|
||||||
|
|
||||||
|
public bool EnableEnhancedNvdecDecoder { get; set; }
|
||||||
|
|
||||||
public bool EnableHardwareEncoding { get; set; }
|
public bool EnableHardwareEncoding { get; set; }
|
||||||
|
|
||||||
public bool AllowHevcEncoding { get; set; }
|
public bool AllowHevcEncoding { get; set; }
|
||||||
|
@ -88,6 +92,7 @@ namespace MediaBrowser.Model.Configuration
|
||||||
// The left side of the dot is the platform number, and the right side is the device number on the platform.
|
// The left side of the dot is the platform number, and the right side is the device number on the platform.
|
||||||
OpenclDevice = "0.0";
|
OpenclDevice = "0.0";
|
||||||
EnableTonemapping = false;
|
EnableTonemapping = false;
|
||||||
|
EnableVppTonemapping = false;
|
||||||
TonemappingAlgorithm = "hable";
|
TonemappingAlgorithm = "hable";
|
||||||
TonemappingRange = "auto";
|
TonemappingRange = "auto";
|
||||||
TonemappingDesat = 0;
|
TonemappingDesat = 0;
|
||||||
|
@ -100,6 +105,7 @@ namespace MediaBrowser.Model.Configuration
|
||||||
DeinterlaceMethod = "yadif";
|
DeinterlaceMethod = "yadif";
|
||||||
EnableDecodingColorDepth10Hevc = true;
|
EnableDecodingColorDepth10Hevc = true;
|
||||||
EnableDecodingColorDepth10Vp9 = true;
|
EnableDecodingColorDepth10Vp9 = true;
|
||||||
|
EnableEnhancedNvdecDecoder = true;
|
||||||
EnableHardwareEncoding = true;
|
EnableHardwareEncoding = true;
|
||||||
AllowHevcEncoding = true;
|
AllowHevcEncoding = true;
|
||||||
EnableSubtitleExtraction = true;
|
EnableSubtitleExtraction = true;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors>Jellyfin Contributors</Authors>
|
<Authors>Jellyfin Contributors</Authors>
|
||||||
<PackageId>Jellyfin.Model</PackageId>
|
<PackageId>Jellyfin.Model</PackageId>
|
||||||
<VersionPrefix>10.7.0</VersionPrefix>
|
<VersionPrefix>10.8.0</VersionPrefix>
|
||||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -785,20 +785,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "musicBrainzArtistID":
|
|
||||||
{
|
|
||||||
if (reader.IsEmptyElement)
|
|
||||||
{
|
|
||||||
reader.Read();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var id = reader.ReadElementContentAsString();
|
|
||||||
item.SetProviderId(MetadataProvider.MusicBrainzArtist.ToString(), id);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
string readerName = reader.Name;
|
string readerName = reader.Name;
|
||||||
if (_validProviderIds.TryGetValue(readerName, out string? providerIdValue))
|
if (_validProviderIds.TryGetValue(readerName, out string? providerIdValue))
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
[assembly: AssemblyVersion("10.7.0")]
|
[assembly: AssemblyVersion("10.8.0")]
|
||||||
[assembly: AssemblyFileVersion("10.7.0")]
|
[assembly: AssemblyFileVersion("10.8.0")]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
# We just wrap `build` so this is really it
|
# We just wrap `build` so this is really it
|
||||||
name: "jellyfin"
|
name: "jellyfin"
|
||||||
version: "10.7.0"
|
version: "10.8.0"
|
||||||
packages:
|
packages:
|
||||||
- debian.amd64
|
- debian.amd64
|
||||||
- debian.arm64
|
- debian.arm64
|
||||||
|
|
6
debian/changelog
vendored
6
debian/changelog
vendored
|
@ -1,3 +1,9 @@
|
||||||
|
jellyfin-server (10.8.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
|
* Forthcoming stable release
|
||||||
|
|
||||||
|
-- Jellyfin Packaging Team <packaging@jellyfin.org> Fri, 04 Dec 2020 21:55:12 -0500
|
||||||
|
|
||||||
jellyfin-server (10.7.0-1) unstable; urgency=medium
|
jellyfin-server (10.7.0-1) unstable; urgency=medium
|
||||||
|
|
||||||
* Forthcoming stable release
|
* Forthcoming stable release
|
||||||
|
|
2
debian/metapackage/jellyfin
vendored
2
debian/metapackage/jellyfin
vendored
|
@ -5,7 +5,7 @@ Homepage: https://jellyfin.org
|
||||||
Standards-Version: 3.9.2
|
Standards-Version: 3.9.2
|
||||||
|
|
||||||
Package: jellyfin
|
Package: jellyfin
|
||||||
Version: 10.7.0
|
Version: 10.8.0
|
||||||
Maintainer: Jellyfin Packaging Team <packaging@jellyfin.org>
|
Maintainer: Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||||
Depends: jellyfin-server, jellyfin-web
|
Depends: jellyfin-server, jellyfin-web
|
||||||
Description: Provides the Jellyfin Free Software Media System
|
Description: Provides the Jellyfin Free Software Media System
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -15,7 +15,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -15,7 +15,7 @@ RUN apt-get update \
|
||||||
|
|
||||||
# Install dotnet repository
|
# Install dotnet repository
|
||||||
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
# https://dotnet.microsoft.com/download/linux-package-manager/debian9/sdk-current
|
||||||
RUN wget https://download.visualstudio.microsoft.com/download/pr/7f736160-9f34-4595-8d72-13630c437aef/b9c4513afb0f8872eb95793c70ac52f6/dotnet-sdk-5.0.102-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
RUN wget https://download.visualstudio.microsoft.com/download/pr/a2052604-de46-4cd4-8256-9bc222537d32/a798771950904eaf91c0c37c58f516e1/dotnet-sdk-5.0.103-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||||
&& mkdir -p dotnet-sdk \
|
&& mkdir -p dotnet-sdk \
|
||||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
Name: jellyfin
|
Name: jellyfin
|
||||||
Version: 10.7.0
|
Version: 10.8.0
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: The Free Software Media System
|
Summary: The Free Software Media System
|
||||||
License: GPLv3
|
License: GPLv3
|
||||||
|
@ -137,6 +137,8 @@ fi
|
||||||
%systemd_postun_with_restart jellyfin.service
|
%systemd_postun_with_restart jellyfin.service
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Dec 04 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||||
|
- Forthcoming stable release
|
||||||
* Mon Jul 27 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
* Mon Jul 27 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||||
- Forthcoming stable release
|
- Forthcoming stable release
|
||||||
* Mon Mar 23 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
* Mon Mar 23 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<PackageReference Include="AutoFixture" Version="4.15.0" />
|
<PackageReference Include="AutoFixture" Version="4.15.0" />
|
||||||
<PackageReference Include="AutoFixture.AutoMoq" Version="4.15.0" />
|
<PackageReference Include="AutoFixture.AutoMoq" Version="4.15.0" />
|
||||||
<PackageReference Include="AutoFixture.Xunit2" Version="4.15.0" />
|
<PackageReference Include="AutoFixture.Xunit2" Version="4.15.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.2" />
|
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.3" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||||
<PackageReference Include="xunit" Version="2.4.1" />
|
<PackageReference Include="xunit" Version="2.4.1" />
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using Emby.Server.Implementations.HttpServer;
|
||||||
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Jellyfin.Server.Implementations.Tests.HttpServer
|
||||||
|
{
|
||||||
|
public class WebSocketConnectionTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void DeserializeWebSocketMessage_SingleSegment_Success()
|
||||||
|
{
|
||||||
|
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||||
|
var bytes = File.ReadAllBytes("Test Data/HttpServer/ForceKeepAlive.json");
|
||||||
|
con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(bytes), out var bytesConsumed);
|
||||||
|
Assert.Equal(109, bytesConsumed);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DeserializeWebSocketMessage_MultipleSegments_Success()
|
||||||
|
{
|
||||||
|
const int SplitPos = 64;
|
||||||
|
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||||
|
var bytes = File.ReadAllBytes("Test Data/HttpServer/ForceKeepAlive.json");
|
||||||
|
var seg1 = new BufferSegment(new Memory<byte>(bytes, 0, SplitPos));
|
||||||
|
var seg2 = seg1.Append(new Memory<byte>(bytes, SplitPos, bytes.Length - SplitPos));
|
||||||
|
con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(seg1, 0, seg2, seg2.Memory.Length - 1), out var bytesConsumed);
|
||||||
|
Assert.Equal(109, bytesConsumed);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DeserializeWebSocketMessage_ValidPartial_Success()
|
||||||
|
{
|
||||||
|
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||||
|
var bytes = File.ReadAllBytes("Test Data/HttpServer/ValidPartial.json");
|
||||||
|
con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(bytes), out var bytesConsumed);
|
||||||
|
Assert.Equal(109, bytesConsumed);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void DeserializeWebSocketMessage_Partial_ThrowJsonException()
|
||||||
|
{
|
||||||
|
var con = new WebSocketConnection(new NullLogger<WebSocketConnection>(), null!, null!, null!);
|
||||||
|
var bytes = File.ReadAllBytes("Test Data/HttpServer/Partial.json");
|
||||||
|
Assert.Throws<JsonException>(() => con.DeserializeWebSocketMessage(new ReadOnlySequence<byte>(bytes), out var bytesConsumed));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class BufferSegment : ReadOnlySequenceSegment<byte>
|
||||||
|
{
|
||||||
|
public BufferSegment(Memory<byte> memory)
|
||||||
|
{
|
||||||
|
Memory = memory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferSegment Append(Memory<byte> memory)
|
||||||
|
{
|
||||||
|
var segment = new BufferSegment(memory)
|
||||||
|
{
|
||||||
|
RunningIndex = RunningIndex + Memory.Length
|
||||||
|
};
|
||||||
|
Next = segment;
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,12 @@
|
||||||
<RootNamespace>Jellyfin.Server.Implementations.Tests</RootNamespace>
|
<RootNamespace>Jellyfin.Server.Implementations.Tests</RootNamespace>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Test Data\**\*.*">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AutoFixture" Version="4.15.0" />
|
<PackageReference Include="AutoFixture" Version="4.15.0" />
|
||||||
<PackageReference Include="AutoFixture.AutoMoq" Version="4.15.0" />
|
<PackageReference Include="AutoFixture.AutoMoq" Version="4.15.0" />
|
||||||
|
@ -35,11 +41,6 @@
|
||||||
<ProjectReference Include="..\..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
|
<ProjectReference Include="..\..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="LiveTv\discover.json" />
|
|
||||||
<EmbeddedResource Include="LiveTv\lineup.json" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
<CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>../jellyfin-tests.ruleset</CodeAnalysisRuleSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -21,24 +22,15 @@ namespace Jellyfin.Server.Implementations.Tests.LiveTv
|
||||||
|
|
||||||
public HdHomerunHostTests()
|
public HdHomerunHostTests()
|
||||||
{
|
{
|
||||||
const string BaseResourcePath = "Jellyfin.Server.Implementations.Tests.LiveTv.";
|
|
||||||
|
|
||||||
var messageHandler = new Mock<HttpMessageHandler>();
|
var messageHandler = new Mock<HttpMessageHandler>();
|
||||||
messageHandler.Protected()
|
messageHandler.Protected()
|
||||||
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
|
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
|
||||||
.Returns<HttpRequestMessage, CancellationToken>(
|
.Returns<HttpRequestMessage, CancellationToken>(
|
||||||
(m, _) =>
|
(m, _) =>
|
||||||
{
|
{
|
||||||
var resource = BaseResourcePath + m.RequestUri?.Segments[^1];
|
|
||||||
var stream = typeof(HdHomerunHostTests).Assembly.GetManifestResourceStream(resource);
|
|
||||||
if (stream == null)
|
|
||||||
{
|
|
||||||
throw new NullReferenceException("Resource doesn't exist: " + resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.FromResult(new HttpResponseMessage()
|
return Task.FromResult(new HttpResponseMessage()
|
||||||
{
|
{
|
||||||
Content = new StreamContent(stream)
|
Content = new StreamContent(File.OpenRead("Test Data/LiveTv/" + m.RequestUri?.Segments[^1]))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using Emby.Server.Implementations.Plugins;
|
||||||
|
using MediaBrowser.Common.Plugins;
|
||||||
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Jellyfin.Server.Implementations.Tests.Plugins
|
||||||
|
{
|
||||||
|
public class PluginManagerTests
|
||||||
|
{
|
||||||
|
private static readonly string _testPathRoot = Path.Combine(Path.GetTempPath(), "jellyfin-test-data");
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SaveManifest_RoundTrip_Success()
|
||||||
|
{
|
||||||
|
var pluginManager = new PluginManager(new NullLogger<PluginManager>(), null!, null!, null!, new Version(1, 0));
|
||||||
|
var manifest = new PluginManifest()
|
||||||
|
{
|
||||||
|
Version = "1.0"
|
||||||
|
};
|
||||||
|
|
||||||
|
var tempPath = Path.Combine(_testPathRoot, "manifest-" + Path.GetRandomFileName());
|
||||||
|
Directory.CreateDirectory(tempPath);
|
||||||
|
|
||||||
|
Assert.True(pluginManager.SaveManifest(manifest, tempPath));
|
||||||
|
|
||||||
|
var res = pluginManager.LoadManifest(tempPath);
|
||||||
|
|
||||||
|
Assert.Equal(manifest.Category, res.Manifest.Category);
|
||||||
|
Assert.Equal(manifest.Changelog, res.Manifest.Changelog);
|
||||||
|
Assert.Equal(manifest.Description, res.Manifest.Description);
|
||||||
|
Assert.Equal(manifest.Id, res.Manifest.Id);
|
||||||
|
Assert.Equal(manifest.Name, res.Manifest.Name);
|
||||||
|
Assert.Equal(manifest.Overview, res.Manifest.Overview);
|
||||||
|
Assert.Equal(manifest.Owner, res.Manifest.Owner);
|
||||||
|
Assert.Equal(manifest.TargetAbi, res.Manifest.TargetAbi);
|
||||||
|
Assert.Equal(manifest.Timestamp, res.Manifest.Timestamp);
|
||||||
|
Assert.Equal(manifest.Version, res.Manifest.Version);
|
||||||
|
Assert.Equal(manifest.Status, res.Manifest.Status);
|
||||||
|
Assert.Equal(manifest.AutoUpdate, res.Manifest.AutoUpdate);
|
||||||
|
Assert.Equal(manifest.ImagePath, res.Manifest.ImagePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
{"MessageType":"ForceKeepAlive","MessageId":"00000000-0000-0000-0000-000000000000","ServerId":null,"Data":60}
|
|
@ -0,0 +1 @@
|
||||||
|
{"MessageType":"KeepAlive","MessageId":"d29ef449-6965-4000
|
|
@ -0,0 +1 @@
|
||||||
|
{"MessageType":"ForceKeepAlive","MessageId":"00000000-0000-0000-0000-000000000000","ServerId":null,"Data":60}{"MessageType":"KeepAlive","MessageId":"d29ef449-6965-4000
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="../../MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj" />
|
<ProjectReference Include="../../MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj" />
|
||||||
|
<ProjectReference Include="../../MediaBrowser.Providers/MediaBrowser.Providers.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
|
|
@ -8,6 +8,7 @@ using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
using MediaBrowser.Providers.Movies;
|
||||||
using MediaBrowser.XbmcMetadata.Parsers;
|
using MediaBrowser.XbmcMetadata.Parsers;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -24,8 +25,13 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||||
public EpisodeNfoProviderTests()
|
public EpisodeNfoProviderTests()
|
||||||
{
|
{
|
||||||
var providerManager = new Mock<IProviderManager>();
|
var providerManager = new Mock<IProviderManager>();
|
||||||
|
|
||||||
|
var imdbExternalId = new ImdbExternalId();
|
||||||
|
var externalIdInfo = new ExternalIdInfo(imdbExternalId.ProviderName, imdbExternalId.Key, imdbExternalId.Type, imdbExternalId.UrlFormatString);
|
||||||
|
|
||||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
.Returns(new[] { externalIdInfo });
|
||||||
|
|
||||||
var config = new Mock<IConfigurationManager>();
|
var config = new Mock<IConfigurationManager>();
|
||||||
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
||||||
.Returns(new XbmcMetadataOptions());
|
.Returns(new XbmcMetadataOptions());
|
||||||
|
@ -60,6 +66,8 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||||
Assert.Equal(2017, item.ProductionYear);
|
Assert.Equal(2017, item.ProductionYear);
|
||||||
Assert.Single(item.Studios);
|
Assert.Single(item.Studios);
|
||||||
Assert.Contains("Starz", item.Studios);
|
Assert.Contains("Starz", item.Studios);
|
||||||
|
Assert.Equal("tt5017734", item.ProviderIds[MetadataProvider.Imdb.ToString()]);
|
||||||
|
Assert.Equal("1276153", item.ProviderIds[MetadataProvider.Tmdb.ToString()]);
|
||||||
|
|
||||||
// Credits
|
// Credits
|
||||||
var writers = result.People.Where(x => x.Type == PersonType.Writer).ToArray();
|
var writers = result.People.Where(x => x.Type == PersonType.Writer).ToArray();
|
||||||
|
|
|
@ -9,6 +9,7 @@ using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
using MediaBrowser.Providers.Plugins.Tmdb.Movies;
|
||||||
using MediaBrowser.XbmcMetadata.Parsers;
|
using MediaBrowser.XbmcMetadata.Parsers;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -27,8 +28,12 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||||
_testUser = new User("Test User", "Auth provider", "Reset provider");
|
_testUser = new User("Test User", "Auth provider", "Reset provider");
|
||||||
|
|
||||||
var providerManager = new Mock<IProviderManager>();
|
var providerManager = new Mock<IProviderManager>();
|
||||||
|
|
||||||
|
var tmdbExternalId = new TmdbMovieExternalId();
|
||||||
|
var externalIdInfo = new ExternalIdInfo(tmdbExternalId.ProviderName, tmdbExternalId.Key, tmdbExternalId.Type, tmdbExternalId.UrlFormatString);
|
||||||
|
|
||||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
.Returns(new[] { externalIdInfo });
|
||||||
|
|
||||||
var nfoConfig = new XbmcMetadataOptions()
|
var nfoConfig = new XbmcMetadataOptions()
|
||||||
{
|
{
|
||||||
|
@ -63,7 +68,8 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||||
|
|
||||||
Assert.Equal("Justice League", item.OriginalTitle);
|
Assert.Equal("Justice League", item.OriginalTitle);
|
||||||
Assert.Equal("Justice for all.", item.Tagline);
|
Assert.Equal("Justice for all.", item.Tagline);
|
||||||
Assert.Equal("tt0974015", item.ProviderIds["imdb"]);
|
Assert.Equal("tt0974015", item.ProviderIds[MetadataProvider.Imdb.ToString()]);
|
||||||
|
Assert.Equal("141052", item.ProviderIds[MetadataProvider.Tmdb.ToString()]);
|
||||||
|
|
||||||
Assert.Equal(4, item.Genres.Length);
|
Assert.Equal(4, item.Genres.Length);
|
||||||
Assert.Contains("Action", item.Genres);
|
Assert.Contains("Action", item.Genres);
|
||||||
|
|
|
@ -10,6 +10,8 @@ using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
using MediaBrowser.Providers.Music;
|
||||||
|
using MediaBrowser.Providers.Plugins.MusicBrainz;
|
||||||
using MediaBrowser.XbmcMetadata.Parsers;
|
using MediaBrowser.XbmcMetadata.Parsers;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -24,8 +26,13 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||||
public MusicAlbumNfoProviderTests()
|
public MusicAlbumNfoProviderTests()
|
||||||
{
|
{
|
||||||
var providerManager = new Mock<IProviderManager>();
|
var providerManager = new Mock<IProviderManager>();
|
||||||
|
|
||||||
|
var musicBrainzArtist = new MusicBrainzArtistExternalId();
|
||||||
|
var externalIdInfo = new ExternalIdInfo(musicBrainzArtist.ProviderName, musicBrainzArtist.Key, musicBrainzArtist.Type, "MusicBrainzServer");
|
||||||
|
|
||||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
.Returns(new[] { externalIdInfo });
|
||||||
|
|
||||||
var config = new Mock<IConfigurationManager>();
|
var config = new Mock<IConfigurationManager>();
|
||||||
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
||||||
.Returns(new XbmcMetadataOptions());
|
.Returns(new XbmcMetadataOptions());
|
||||||
|
|
|
@ -8,6 +8,7 @@ using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Providers;
|
using MediaBrowser.Model.Providers;
|
||||||
|
using MediaBrowser.Providers.Music;
|
||||||
using MediaBrowser.XbmcMetadata.Parsers;
|
using MediaBrowser.XbmcMetadata.Parsers;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
@ -22,8 +23,13 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||||
public MusicArtistNfoParserTests()
|
public MusicArtistNfoParserTests()
|
||||||
{
|
{
|
||||||
var providerManager = new Mock<IProviderManager>();
|
var providerManager = new Mock<IProviderManager>();
|
||||||
|
|
||||||
|
var musicBrainzArtist = new MusicBrainzArtistExternalId();
|
||||||
|
var externalIdInfo = new ExternalIdInfo(musicBrainzArtist.ProviderName, musicBrainzArtist.Key, musicBrainzArtist.Type, "MusicBrainzServer");
|
||||||
|
|
||||||
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
providerManager.Setup(x => x.GetExternalIdInfos(It.IsAny<IHasProviderIds>()))
|
||||||
.Returns(Enumerable.Empty<ExternalIdInfo>());
|
.Returns(new[] { externalIdInfo });
|
||||||
|
|
||||||
var config = new Mock<IConfigurationManager>();
|
var config = new Mock<IConfigurationManager>();
|
||||||
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
config.Setup(x => x.GetConfiguration(It.IsAny<string>()))
|
||||||
.Returns(new XbmcMetadataOptions());
|
.Returns(new XbmcMetadataOptions());
|
||||||
|
|
|
@ -47,8 +47,8 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
|
||||||
Assert.Equal("American Gods", item.OriginalTitle);
|
Assert.Equal("American Gods", item.OriginalTitle);
|
||||||
Assert.Equal(string.Empty, item.Tagline);
|
Assert.Equal(string.Empty, item.Tagline);
|
||||||
Assert.Equal(0, item.RunTimeTicks);
|
Assert.Equal(0, item.RunTimeTicks);
|
||||||
Assert.Equal("46639", item.ProviderIds["tmdb"]);
|
Assert.Equal("46639", item.ProviderIds[MetadataProvider.Tmdb.ToString()]);
|
||||||
Assert.Equal("253573", item.ProviderIds["tvdb"]);
|
Assert.Equal("253573", item.ProviderIds[MetadataProvider.Tvdb.ToString()]);
|
||||||
|
|
||||||
Assert.Equal(3, item.Genres.Length);
|
Assert.Equal(3, item.Genres.Length);
|
||||||
Assert.Contains("Drama", item.Genres);
|
Assert.Contains("Drama", item.Genres);
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
<playcount>2</playcount>
|
<playcount>2</playcount>
|
||||||
<watched>true</watched>
|
<watched>true</watched>
|
||||||
<lastplayed>2021-02-11 07:47:23</lastplayed>
|
<lastplayed>2021-02-11 07:47:23</lastplayed>
|
||||||
|
<tmdbId>141052</tmdbId>
|
||||||
<thumb aspect="set.poster" preview="https://assets.fanart.tv/preview/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg">https://assets.fanart.tv/fanart/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg</thumb>
|
<thumb aspect="set.poster" preview="https://assets.fanart.tv/preview/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg">https://assets.fanart.tv/fanart/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg</thumb>
|
||||||
<thumb aspect="set.poster" preview="https://assets.fanart.tv/preview/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg">https://assets.fanart.tv/fanart/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg</thumb>
|
<thumb aspect="set.poster" preview="https://assets.fanart.tv/preview/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg">https://assets.fanart.tv/fanart/movies/468551/movieposter/justice-league-collection-5c24ea65591d3.jpg</thumb>
|
||||||
<thumb aspect="set.clearlogo" preview="https://assets.fanart.tv/preview/movies/468551/hdmovielogo/justice-league-collection-5ba855ed4239a.png">https://assets.fanart.tv/fanart/movies/468551/hdmovielogo/justice-league-collection-5ba855ed4239a.png</thumb>
|
<thumb aspect="set.clearlogo" preview="https://assets.fanart.tv/preview/movies/468551/hdmovielogo/justice-league-collection-5ba855ed4239a.png">https://assets.fanart.tv/fanart/movies/468551/hdmovielogo/justice-league-collection-5ba855ed4239a.png</thumb>
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
<lastplayed></lastplayed>
|
<lastplayed></lastplayed>
|
||||||
<id>1276153</id>
|
<id>1276153</id>
|
||||||
<uniqueid type="tmdb" default="true">1276153</uniqueid>
|
<uniqueid type="tmdb" default="true">1276153</uniqueid>
|
||||||
|
<imdbId>tt5017734</imdbId>
|
||||||
<genre>Drama</genre>
|
<genre>Drama</genre>
|
||||||
<genre>Mystery</genre>
|
<genre>Mystery</genre>
|
||||||
<genre>Sci-Fi & Fantasy</genre>
|
<genre>Sci-Fi & Fantasy</genre>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user