Merge remote-tracking branch 'jellyfin/master' into nfo-tests
# Conflicts: # tests/Jellyfin.XbmcMetadata.Tests/Parsers/EpisodeNfoProviderTests.cs # tests/Jellyfin.XbmcMetadata.Tests/Parsers/SeriesNfoParserTests.cs
This commit is contained in:
commit
fc7377fb9b
|
@ -7,7 +7,7 @@ parameters:
|
|||
default: "ubuntu-latest"
|
||||
- name: DotNetSdkVersion
|
||||
type: string
|
||||
default: 5.0.100
|
||||
default: 5.0.103
|
||||
|
||||
jobs:
|
||||
- job: CompatibilityCheck
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
default: "ubuntu-latest"
|
||||
- name: GeneratorVersion
|
||||
type: string
|
||||
default: "5.0.0-beta2"
|
||||
default: "5.0.1"
|
||||
|
||||
jobs:
|
||||
- job: GenerateApiClients
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
parameters:
|
||||
LinuxImage: 'ubuntu-latest'
|
||||
RestoreBuildProjects: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
||||
DotNetSdkVersion: 5.0.100
|
||||
DotNetSdkVersion: 5.0.103
|
||||
|
||||
jobs:
|
||||
- job: Build
|
||||
|
|
|
@ -10,7 +10,7 @@ parameters:
|
|||
default: "tests/**/*Tests.csproj"
|
||||
- name: DotNetSdkVersion
|
||||
type: string
|
||||
default: 5.0.100
|
||||
default: 5.0.103
|
||||
|
||||
jobs:
|
||||
- job: Test
|
||||
|
|
|
@ -6,7 +6,7 @@ variables:
|
|||
- name: RestoreBuildProjects
|
||||
value: 'Jellyfin.Server/Jellyfin.Server.csproj'
|
||||
- name: DotNetSdkVersion
|
||||
value: 5.0.100
|
||||
value: 5.0.103
|
||||
|
||||
pr:
|
||||
autoCancel: true
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
|||
|
||||
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",
|
||||
|
||||
Headers = new[]
|
||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
|||
new HttpHeaderInfo
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
|||
|
||||
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",
|
||||
|
||||
Headers = new[]
|
||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
|||
new HttpHeaderInfo
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
|||
|
||||
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",
|
||||
|
||||
Headers = new[]
|
||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
|||
new HttpHeaderInfo
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
|||
|
||||
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",
|
||||
|
||||
Headers = new[]
|
||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
|||
new HttpHeaderInfo
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Emby.Dlna.Profiles
|
|||
|
||||
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",
|
||||
|
||||
Headers = new[]
|
||||
|
@ -21,7 +21,7 @@ namespace Emby.Dlna.Profiles
|
|||
new 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).*",
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Name>Sony Bravia (2010)</Name>
|
||||
<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>
|
||||
<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>
|
||||
</Identification>
|
||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Name>Sony Bravia (2011)</Name>
|
||||
<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>
|
||||
<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>
|
||||
</Identification>
|
||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Name>Sony Bravia (2012)</Name>
|
||||
<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>
|
||||
<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>
|
||||
</Identification>
|
||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Name>Sony Bravia (2013)</Name>
|
||||
<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>
|
||||
<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>
|
||||
</Identification>
|
||||
<Manufacturer>Microsoft Corporation</Manufacturer>
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Name>Sony Bravia (2014)</Name>
|
||||
<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>
|
||||
<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>
|
||||
</Identification>
|
||||
<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
|
||||
// [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
|
||||
},
|
||||
|
@ -588,7 +588,7 @@ namespace Emby.Naming.Common
|
|||
AudioBookNamesExpressions = new[]
|
||||
{
|
||||
// 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*$"
|
||||
};
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Naming</PackageId>
|
||||
<VersionPrefix>10.7.0</VersionPrefix>
|
||||
<VersionPrefix>10.8.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -249,7 +249,7 @@ namespace Emby.Server.Implementations.Dto
|
|||
var activeRecording = liveTvManager.GetActiveRecordingInfo(item.Path);
|
||||
if (activeRecording != null)
|
||||
{
|
||||
dto.Type = "Recording";
|
||||
dto.Type = BaseItemKind.Recording;
|
||||
dto.CanDownload = false;
|
||||
dto.RunTimeTicks = null;
|
||||
|
||||
|
@ -904,7 +904,7 @@ namespace Emby.Server.Implementations.Dto
|
|||
}
|
||||
}
|
||||
|
||||
dto.Type = item.GetClientTypeName();
|
||||
dto.Type = item.GetBaseItemKind();
|
||||
if ((item.CommunityRating ?? 0) > 0)
|
||||
{
|
||||
dto.CommunityRating = item.CommunityRating;
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Buffers;
|
|||
using System.IO.Pipelines;
|
||||
using System.Net;
|
||||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -138,7 +139,7 @@ namespace Emby.Server.Implementations.HttpServer
|
|||
writer.Advance(bytesRead);
|
||||
|
||||
// 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)
|
||||
{
|
||||
// The PipeReader stopped reading
|
||||
|
@ -181,32 +182,16 @@ namespace Emby.Server.Implementations.HttpServer
|
|||
}
|
||||
|
||||
WebSocketMessage<object>? stub;
|
||||
long bytesConsumed = 0;
|
||||
try
|
||||
{
|
||||
|
||||
if (buffer.IsSingleSegment)
|
||||
{
|
||||
stub = JsonSerializer.Deserialize<WebSocketMessage<object>>(buffer.FirstSpan, _jsonOptions);
|
||||
}
|
||||
else
|
||||
{
|
||||
var buf = ArrayPool<byte>.Shared.Rent(Convert.ToInt32(buffer.Length));
|
||||
try
|
||||
{
|
||||
buffer.CopyTo(buf);
|
||||
stub = JsonSerializer.Deserialize<WebSocketMessage<object>>(buf, _jsonOptions);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(buf);
|
||||
}
|
||||
}
|
||||
stub = DeserializeWebSocketMessage(buffer, out bytesConsumed);
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
// Tell the PipeReader how much of the buffer we have consumed
|
||||
reader.AdvanceTo(buffer.End);
|
||||
_logger.LogError(ex, "Error processing web socket message");
|
||||
_logger.LogError(ex, "Error processing web socket message: {Data}", Encoding.UTF8.GetString(buffer));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -217,27 +202,34 @@ namespace Emby.Server.Implementations.HttpServer
|
|||
}
|
||||
|
||||
// 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);
|
||||
|
||||
var info = new WebSocketMessageInfo
|
||||
{
|
||||
MessageType = stub.MessageType,
|
||||
Data = stub.Data?.ToString(), // Data can be null
|
||||
Connection = this
|
||||
};
|
||||
|
||||
if (info.MessageType == SessionMessageType.KeepAlive)
|
||||
if (stub.MessageType == SessionMessageType.KeepAlive)
|
||||
{
|
||||
await SendKeepAliveResponse().ConfigureAwait(false);
|
||||
}
|
||||
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()
|
||||
{
|
||||
LastKeepAliveDate = DateTime.UtcNow;
|
||||
|
|
|
@ -79,11 +79,6 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
|||
return new MusicArtist();
|
||||
}
|
||||
|
||||
if (_config.Configuration.EnableSimpleArtistDetection)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// Avoid mis-identifying top folders
|
||||
if (args.Parent.IsRoot)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
|||
public LegacyHdHomerunChannelCommands(string url)
|
||||
{
|
||||
// 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);
|
||||
if (match.Success)
|
||||
{
|
||||
|
|
|
@ -55,26 +55,26 @@
|
|||
"NotificationOptionPluginInstalled": "Приставката е инсталирана",
|
||||
"NotificationOptionPluginUninstalled": "Приставката е деинсталирана",
|
||||
"NotificationOptionPluginUpdateInstalled": "Обновлението на приставката е инсталирано",
|
||||
"NotificationOptionServerRestartRequired": "Нужно е повторно пускане на сървъра",
|
||||
"NotificationOptionServerRestartRequired": "Сървърът трябва да се рестартира",
|
||||
"NotificationOptionTaskFailed": "Грешка в планирана задача",
|
||||
"NotificationOptionUserLockedOut": "Потребителя е заключен",
|
||||
"NotificationOptionUserLockedOut": "Потребителят е заключен",
|
||||
"NotificationOptionVideoPlayback": "Възпроизвеждането на видео започна",
|
||||
"NotificationOptionVideoPlaybackStopped": "Възпроизвеждането на видео е спряно",
|
||||
"Photos": "Снимки",
|
||||
"Playlists": "Списъци",
|
||||
"Plugin": "Приставка",
|
||||
"PluginInstalledWithName": "{0} е инсталирано",
|
||||
"PluginUninstalledWithName": "{0} е деинсталирано",
|
||||
"PluginUpdatedWithName": "{0} е обновено",
|
||||
"PluginInstalledWithName": "{0} е инсталиранa",
|
||||
"PluginUninstalledWithName": "{0} е деинсталиранa",
|
||||
"PluginUpdatedWithName": "{0} е обновенa",
|
||||
"ProviderValue": "Доставчик: {0}",
|
||||
"ScheduledTaskFailedWithName": "{0} се провали",
|
||||
"ScheduledTaskStartedWithName": "{0} започна",
|
||||
"ServerNameNeedsToBeRestarted": "{0} е нужно да се рестартира",
|
||||
"ServerNameNeedsToBeRestarted": "{0} трябва да се рестартира",
|
||||
"Shows": "Сериали",
|
||||
"Songs": "Песни",
|
||||
"StartupEmbyServerIsLoading": "Сървърът зарежда. Моля, опитайте отново след малко.",
|
||||
"SubtitleDownloadFailureForItem": "Неуспешно изтегляне на субтитри за {0}",
|
||||
"SubtitleDownloadFailureFromForItem": "Поднадписите за {1} от {0} не можаха да се изтеглят",
|
||||
"SubtitleDownloadFailureFromForItem": "Субтитрите за {1} от {0} не можаха да бъдат изтеглени",
|
||||
"Sync": "Синхронизиране",
|
||||
"System": "Система",
|
||||
"TvShows": "Телевизионни сериали",
|
||||
|
@ -92,12 +92,12 @@
|
|||
"ValueHasBeenAddedToLibrary": "{0} беше добавен във Вашата библиотека",
|
||||
"ValueSpecialEpisodeName": "Специални - {0}",
|
||||
"VersionNumber": "Версия {0}",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Търси Интернет за липсващи поднадписи, на база конфигурацията за мета-данни.",
|
||||
"TaskDownloadMissingSubtitles": "Изтегляне на липсващи поднадписи",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Търси Интернет за липсващи субтитри, на база конфигурацията за мета-данни.",
|
||||
"TaskDownloadMissingSubtitles": "Изтегляне на липсващи субтитри",
|
||||
"TaskRefreshChannelsDescription": "Обновява информацията за интернет канала.",
|
||||
"TaskRefreshChannels": "Обновяване на Канали",
|
||||
"TaskCleanTranscodeDescription": "Изтрива прекодирани файлове по-стари от един ден.",
|
||||
"TaskCleanTranscode": "Изчиства директорията за прекодиране",
|
||||
"TaskCleanTranscodeDescription": "Изтрива транскодирани файлове по-стари от един ден.",
|
||||
"TaskCleanTranscode": "Изчиства директорията за транскодиране",
|
||||
"TaskUpdatePluginsDescription": "Изтегля и инсталира актуализации за добавките, които са настроени за автоматична актуализация.",
|
||||
"TaskUpdatePlugins": "Актуализира добавките",
|
||||
"TaskRefreshPeopleDescription": "Актуализира мета-данните за артистите и режисьорите за Вашата медийна библиотека.",
|
||||
|
|
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",
|
||||
"NewVersionIsAvailable": "Uusi versio Jellyfin palvelimesta on ladattavissa.",
|
||||
"HeaderLiveTV": "Live TV",
|
||||
"NewVersionIsAvailable": "Uusi versio Jellyfin-palvelimesta on ladattavissa.",
|
||||
"NameSeasonUnknown": "Tuntematon kausi",
|
||||
"NameSeasonNumber": "Kausi {0}",
|
||||
"NameInstallFailed": "{0} asennus epäonnistui",
|
||||
"MusicVideos": "Musiikkivideot",
|
||||
"Music": "Musiikki",
|
||||
"Movies": "Elokuvat",
|
||||
"MixedContent": "Sekoitettu sisältö",
|
||||
"MixedContent": "Sekalainen sisältö",
|
||||
"MessageServerConfigurationUpdated": "Palvelimen asetukset on päivitetty",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen asetusryhmä {0} on päivitetty",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin palvelin on päivitetty versioon {0}",
|
||||
"MessageApplicationUpdated": "Jellyfin palvelin on päivitetty",
|
||||
"Latest": "Uusimmat",
|
||||
"LabelRunningTimeValue": "Toiston kesto: {0}",
|
||||
"MessageNamedServerConfigurationUpdatedWithValue": "Palvelimen asetusten osio {0} on päivitetty",
|
||||
"MessageApplicationUpdatedTo": "Jellyfin-palvelin on päivitetty versioon {0}",
|
||||
"MessageApplicationUpdated": "Jellyfin-palvelin on päivitetty",
|
||||
"Latest": "Viimeisimmät",
|
||||
"LabelRunningTimeValue": "Kesto: {0}",
|
||||
"LabelIpAddressValue": "IP-osoite: {0}",
|
||||
"ItemRemovedWithName": "{0} poistettiin kirjastosta",
|
||||
"ItemAddedWithName": "{0} lisättiin kirjastoon",
|
||||
"Inherit": "Periytyä",
|
||||
"Inherit": "Peri",
|
||||
"HomeVideos": "Kotivideot",
|
||||
"HeaderRecordingGroups": "Tallennusryhmät",
|
||||
"HeaderNextUp": "Seuraavaksi",
|
||||
"HeaderFavoriteSongs": "Suosikkikappaleet",
|
||||
"HeaderFavoriteShows": "Suosikkisarjat",
|
||||
"HeaderFavoriteEpisodes": "Suosikkijaksot",
|
||||
"HeaderFavoriteArtists": "Suosikkiartistit",
|
||||
"HeaderFavoriteArtists": "Suosikkiesittäjät",
|
||||
"HeaderFavoriteAlbums": "Suosikkialbumit",
|
||||
"HeaderContinueWatching": "Jatka katsomista",
|
||||
"HeaderAlbumArtists": "Albumin artistit",
|
||||
"HeaderContinueWatching": "Jatka katselua",
|
||||
"HeaderAlbumArtists": "Albumin esittäjät",
|
||||
"Genres": "Tyylilajit",
|
||||
"Folders": "Kansiot",
|
||||
"Favorites": "Suosikit",
|
||||
"FailedLoginAttemptWithUserName": "Kirjautuminen epäonnistui kohteesta {0}",
|
||||
"FailedLoginAttemptWithUserName": "Epäonnistunut kirjautumisyritys lähteestä \"{0}\"",
|
||||
"DeviceOnlineWithName": "{0} on yhdistetty",
|
||||
"DeviceOfflineWithName": "{0} yhteys on katkaistu",
|
||||
"DeviceOfflineWithName": "{0} on katkaissut yhteyden",
|
||||
"Collections": "Kokoelmat",
|
||||
"ChapterNameValue": "Jakso: {0}",
|
||||
"ChapterNameValue": "Kappale {0}",
|
||||
"Channels": "Kanavat",
|
||||
"CameraImageUploadedFrom": "Uusi kamerakuva on ladattu {0}",
|
||||
"CameraImageUploadedFrom": "Uusi kameran kuva on sirretty lähteestä {0}",
|
||||
"Books": "Kirjat",
|
||||
"AuthenticationSucceededWithUserName": "Käyttäjän {0} todennus onnistui",
|
||||
"Artists": "Artistit",
|
||||
"AuthenticationSucceededWithUserName": "{0} on todennettu",
|
||||
"Artists": "Esittäjät",
|
||||
"Application": "Sovellus",
|
||||
"AppDeviceValues": "Sovellus: {0}, Laite: {1}",
|
||||
"Albums": "Albumit",
|
||||
"User": "Käyttäjä",
|
||||
"System": "Järjestelmä",
|
||||
"ScheduledTaskFailedWithName": "{0} epäonnistui",
|
||||
"PluginUpdatedWithName": "{0} päivitetty",
|
||||
"PluginInstalledWithName": "{0} asennettu",
|
||||
"Photos": "Kuvat",
|
||||
"ScheduledTaskStartedWithName": "{0} aloitettu",
|
||||
"PluginUninstalledWithName": "{0} poistettu",
|
||||
"PluginUpdatedWithName": "{0} päivitettiin",
|
||||
"PluginInstalledWithName": "{0} asennettiin",
|
||||
"Photos": "Valokuvat",
|
||||
"ScheduledTaskStartedWithName": "\"{0}\" käynnistetty",
|
||||
"PluginUninstalledWithName": "{0} poistettiin",
|
||||
"Playlists": "Soittolistat",
|
||||
"VersionNumber": "Versio {0}",
|
||||
"ValueSpecialEpisodeName": "Erikois - {0}",
|
||||
"ValueHasBeenAddedToLibrary": "{0} lisättiin mediakirjastoon",
|
||||
"UserStoppedPlayingItemWithValues": "{0} toistaminen valmistui {1} laitteella {2}",
|
||||
"UserStartedPlayingItemWithValues": "{0} toistaa {1} laitteella {2}",
|
||||
"UserPolicyUpdatedWithName": "Käyttöoikeudet päivitetty käyttäjälle {0}",
|
||||
"UserPasswordChangedWithName": "Salasana vaihdettu käyttäjälle {0}",
|
||||
"UserOnlineFromDevice": "{0} on paikalla osoitteesta {1}",
|
||||
"UserOfflineFromDevice": "{0} yhteys katkaistu kohteesta {1}",
|
||||
"UserLockedOutWithName": "Käyttäjä {0} lukittu",
|
||||
"UserDownloadingItemWithValues": "{0} lataa {1}",
|
||||
"UserDeletedWithName": "Käyttäjä {0} poistettu",
|
||||
"UserCreatedWithName": "Käyttäjä {0} luotu",
|
||||
"TvShows": "TV-ohjelmat",
|
||||
"Sync": "Synkronoi",
|
||||
"SubtitleDownloadFailureFromForItem": "Tekstitystä ei voitu ladata osoitteesta {0} kohteelle {1}",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin palvelin latautuu. Yritä hetken kuluttua uudelleen.",
|
||||
"ValueSpecialEpisodeName": "Erikoisjakso - {0}",
|
||||
"ValueHasBeenAddedToLibrary": "\"{0}\" on lisätty mediakirjastoon",
|
||||
"UserStoppedPlayingItemWithValues": "{0} lopetti kohteen \"{1}\" toiston sijainnissa \"{2}\"",
|
||||
"UserStartedPlayingItemWithValues": "{0} toistaa kohdetta \"{1}\" sijainnissa \"{2}\"",
|
||||
"UserPolicyUpdatedWithName": "Käyttäjän {0} käyttöoikeudet on päivitetty",
|
||||
"UserPasswordChangedWithName": "Käyttäjän {0} salasana on vaihdettu",
|
||||
"UserOnlineFromDevice": "{0} on yhdistänyt sijainnista \"{1}\"",
|
||||
"UserOfflineFromDevice": "{0} on katkaissut yhteyden sijainnista \"{1}\"",
|
||||
"UserLockedOutWithName": "Käyttäjä {0} on lukittu",
|
||||
"UserDownloadingItemWithValues": "{0} lataa kohdetta \"{1}\"",
|
||||
"UserDeletedWithName": "Käyttäjä {0} on poistettu",
|
||||
"UserCreatedWithName": "Käyttäjä {0} on luotu",
|
||||
"TvShows": "Sarjat",
|
||||
"Sync": "Synkronointi",
|
||||
"SubtitleDownloadFailureFromForItem": "Tekstityksen lataus lähteestä \"{0}\" kohteelle \"{1}\" epäonnistui",
|
||||
"StartupEmbyServerIsLoading": "Jellyfin-palvelin latautuu. Yritä hetken kuluttua uudelleen.",
|
||||
"Songs": "Kappaleet",
|
||||
"Shows": "Ohjelmat",
|
||||
"ServerNameNeedsToBeRestarted": "{0} on käynnistettävä uudelleen",
|
||||
"ProviderValue": "Tarjoaja: {0}",
|
||||
"Plugin": "Liitännäinen",
|
||||
"NotificationOptionVideoPlaybackStopped": "Videon toisto pysäytetty",
|
||||
"NotificationOptionVideoPlayback": "Videota toistetaan",
|
||||
"NotificationOptionUserLockedOut": "Käyttäjä kirjautui ulos",
|
||||
"NotificationOptionTaskFailed": "Ajastettu tehtävä epäonnistui",
|
||||
"NotificationOptionServerRestartRequired": "Palvelin on käynnistettävä uudelleen",
|
||||
"NotificationOptionPluginUpdateInstalled": "Liitännäinen päivitetty",
|
||||
"NotificationOptionPluginUninstalled": "Liitännäinen poistettu",
|
||||
"NotificationOptionPluginInstalled": "Liitännäinen asennettu",
|
||||
"NotificationOptionPluginError": "Ongelma liitännäisessä",
|
||||
"NotificationOptionNewLibraryContent": "Uutta sisältöä lisätty",
|
||||
"Shows": "Sarjat",
|
||||
"ServerNameNeedsToBeRestarted": "\"{0}\" on käynnistettävä uudelleen",
|
||||
"ProviderValue": "Lähde: {0}",
|
||||
"Plugin": "Laajennus",
|
||||
"NotificationOptionVideoPlaybackStopped": "Videon toisto lopetettu",
|
||||
"NotificationOptionVideoPlayback": "Videon toisto aloitettu",
|
||||
"NotificationOptionUserLockedOut": "Käyttäjä on lukittu",
|
||||
"NotificationOptionTaskFailed": "Ajoitettu tehtävä epäonnistui",
|
||||
"NotificationOptionServerRestartRequired": "Tarvitaan palvelimen uudelleenkäynnistys",
|
||||
"NotificationOptionPluginUpdateInstalled": "Laajennus on päivitetty",
|
||||
"NotificationOptionPluginUninstalled": "Laajennus on poistettu",
|
||||
"NotificationOptionPluginInstalled": "Laajennus on asennettu",
|
||||
"NotificationOptionPluginError": "Laajennuksen virhe",
|
||||
"NotificationOptionNewLibraryContent": "Sisältöä on lisätty",
|
||||
"NotificationOptionInstallationFailed": "Asennus epäonnistui",
|
||||
"NotificationOptionCameraImageUploaded": "Kameran kuva ladattu",
|
||||
"NotificationOptionCameraImageUploaded": "Kameran kuva on tallennettu",
|
||||
"NotificationOptionAudioPlaybackStopped": "Äänen toisto lopetettu",
|
||||
"NotificationOptionAudioPlayback": "Toistetaan ääntä",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Sovelluspäivitys asennettu",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Ohjelmistopäivitys saatavilla",
|
||||
"NotificationOptionAudioPlayback": "Äänen toisto aloitettu",
|
||||
"NotificationOptionApplicationUpdateInstalled": "Sovelluspäivitys asennettiin",
|
||||
"NotificationOptionApplicationUpdateAvailable": "Sovelluspäivitys on saatavilla",
|
||||
"TasksMaintenanceCategory": "Ylläpito",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Etsii puuttuvia tekstityksiä videon metadatatietojen pohjalta.",
|
||||
"TaskDownloadMissingSubtitlesDescription": "Etsii puuttuvia tekstityksiä määritettyjen metatietoasetusten mukaisesti.",
|
||||
"TaskDownloadMissingSubtitles": "Lataa puuttuvat tekstitykset",
|
||||
"TaskRefreshChannelsDescription": "Päivittää internet-kanavien tiedot.",
|
||||
"TaskRefreshChannels": "Päivitä kanavat",
|
||||
"TaskCleanTranscodeDescription": "Poistaa transkoodatut tiedostot jotka ovat yli päivän vanhoja.",
|
||||
"TaskCleanTranscode": "Puhdista transkoodaushakemisto",
|
||||
"TaskUpdatePluginsDescription": "Lataa ja asentaa päivitykset liitännäisille jotka on asetettu päivittymään automaattisesti.",
|
||||
"TaskUpdatePlugins": "Päivitä liitännäiset",
|
||||
"TaskRefreshPeopleDescription": "Päivittää näyttelijöiden ja ohjaajien mediatiedot kirjastossasi.",
|
||||
"TaskCleanTranscodeDescription": "Poistaa päivää vanhemmat transkoodaustiedostot.",
|
||||
"TaskCleanTranscode": "Puhdista transkoodauskansio",
|
||||
"TaskUpdatePluginsDescription": "Lataa ja asentaa päivitykset laajennuksille, jotka on määritetty päivittymään automaattisesti.",
|
||||
"TaskUpdatePlugins": "Päivitä laajennukset",
|
||||
"TaskRefreshPeopleDescription": "Päivittää mediakirjaston näyttelijöiden ja ohjaajien metatiedot.",
|
||||
"TaskRefreshPeople": "Päivitä henkilöt",
|
||||
"TaskCleanLogsDescription": "Poistaa lokitiedostot jotka ovat yli {0} päivää vanhoja.",
|
||||
"TaskCleanLogs": "Puhdista lokihakemisto",
|
||||
"TaskRefreshLibraryDescription": "Skannaa mediakirjastosi uudet tiedostot ja päivittää metatiedot.",
|
||||
"TaskRefreshLibrary": "Skannaa mediakirjasto",
|
||||
"TaskRefreshChapterImagesDescription": "Luo pienoiskuvat videoille joissa on jaksoja.",
|
||||
"TaskRefreshChapterImages": "Pura jakson kuvat",
|
||||
"TaskCleanCacheDescription": "Poistaa järjestelmälle tarpeettomat väliaikaistiedostot.",
|
||||
"TaskCleanCache": "Tyhjennä välimuisti-hakemisto",
|
||||
"TasksChannelsCategory": "Internet kanavat",
|
||||
"TaskCleanLogsDescription": "Poistaa {0} päivää vanhemmat lokitiedostot.",
|
||||
"TaskCleanLogs": "Siivoa lokikansio",
|
||||
"TaskRefreshLibraryDescription": "Tarkastaa mediakirjastosi sisällön uusien tiedostojen varalta ja päivittää metatiedot.",
|
||||
"TaskRefreshLibrary": "Päivitä mediakirjasto",
|
||||
"TaskRefreshChapterImagesDescription": "Luo esikatselukuvat videoille, jotka sisältävät kappalejaon.",
|
||||
"TaskRefreshChapterImages": "Pura kappalejaon kuvat",
|
||||
"TaskCleanCacheDescription": "Poistaa tarpeettomiksi jääneet väliaikaistiedostot.",
|
||||
"TaskCleanCache": "Tyhjennä välimuistikansio",
|
||||
"TasksChannelsCategory": "Internet-kanavat",
|
||||
"TasksApplicationCategory": "Sovellus",
|
||||
"TasksLibraryCategory": "Kirjasto",
|
||||
"Forced": "Pakotettu",
|
||||
"Default": "Oletus",
|
||||
"TaskCleanActivityLogDescription": "Poistaa määritettyä vanhemmat tapahtumat aktiviteettilokista.",
|
||||
"TaskCleanActivityLog": "Tyhjennä aktiviteettiloki",
|
||||
"TaskCleanActivityLogDescription": "Poistaa määritettyä ikää vanhemmat tapahtumat toimintahistoriasta.",
|
||||
"TaskCleanActivityLog": "Tyhjennä toimintahistoria",
|
||||
"Undefined": "Määrittelemätön"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"Albums": "संग्रह",
|
||||
"Albums": "एल्बम",
|
||||
"HeaderRecordingGroups": "रिकॉर्डिंग समूह",
|
||||
"HeaderNextUp": "इसके बाद",
|
||||
"HeaderLiveTV": "लाइव टीवी",
|
||||
|
@ -26,7 +26,7 @@
|
|||
"AuthenticationSucceededWithUserName": "सफलता से प्रमाणीकृत",
|
||||
"Artists": "कलाकारों",
|
||||
"Application": "एप्लिकेशन",
|
||||
"AppDeviceValues": "एप: {0}, मशीन: {1}",
|
||||
"AppDeviceValues": "एप: {0}, उपकरण: {1}",
|
||||
"NotificationOptionPluginUninstalled": "प्लगइन अनइंस्टाल हो गया",
|
||||
"NotificationOptionPluginInstalled": "प्लगइन इनस्टॉल हो गया",
|
||||
"NotificationOptionPluginError": "प्लगइन फ़ैल हो गया",
|
||||
|
|
|
@ -348,7 +348,7 @@ namespace Emby.Server.Implementations.Plugins
|
|||
try
|
||||
{
|
||||
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;
|
||||
}
|
||||
#pragma warning disable CA1031 // Do not catch general exception types
|
||||
|
@ -519,7 +519,7 @@ namespace Emby.Server.Implementations.Plugins
|
|||
return _plugins.Remove(plugin);
|
||||
}
|
||||
|
||||
private LocalPlugin LoadManifest(string dir)
|
||||
internal LocalPlugin LoadManifest(string dir)
|
||||
{
|
||||
Version? version;
|
||||
PluginManifest? manifest = null;
|
||||
|
|
|
@ -1456,7 +1456,12 @@ namespace Emby.Server.Implementations.Session
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
28
Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
Normal file
28
Jellyfin.Api/Attributes/AcceptsFileAttribute.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
|
||||
namespace Jellyfin.Api.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal produces image attribute.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class AcceptsFileAttribute : Attribute
|
||||
{
|
||||
private readonly string[] _contentTypes;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AcceptsFileAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="contentTypes">Content types this endpoint produces.</param>
|
||||
public AcceptsFileAttribute(params string[] contentTypes)
|
||||
{
|
||||
_contentTypes = contentTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configured content types.
|
||||
/// </summary>
|
||||
/// <returns>the configured content types.</returns>
|
||||
public string[] GetContentTypes() => _contentTypes;
|
||||
}
|
||||
}
|
18
Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs
Normal file
18
Jellyfin.Api/Attributes/AcceptsImageFileAttribute.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
namespace Jellyfin.Api.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Produces file attribute of "image/*".
|
||||
/// </summary>
|
||||
public class AcceptsImageFileAttribute : AcceptsFileAttribute
|
||||
{
|
||||
private const string ContentType = "image/*";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AcceptsImageFileAttribute"/> class.
|
||||
/// </summary>
|
||||
public AcceptsImageFileAttribute()
|
||||
: base(ContentType)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,8 +3,10 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -88,8 +90,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] string? searchTerm,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||
|
@ -127,8 +129,8 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
MediaTypes = mediaTypes,
|
||||
StartIndex = startIndex,
|
||||
Limit = limit,
|
||||
|
@ -287,8 +289,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] string? searchTerm,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||
|
@ -326,8 +328,8 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
MediaTypes = mediaTypes,
|
||||
StartIndex = startIndex,
|
||||
Limit = limit,
|
||||
|
|
|
@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using MediaBrowser.Controller.Collections;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
|
|
|
@ -7,17 +7,11 @@ using Jellyfin.Api.Attributes;
|
|||
using Jellyfin.Api.Models;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Extensions;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Model.Net;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Jellyfin.Api.Controllers
|
||||
{
|
||||
|
|
|
@ -15,7 +15,6 @@ using Jellyfin.Api.Helpers;
|
|||
using Jellyfin.Api.Models.PlaybackDtos;
|
||||
using Jellyfin.Api.Models.StreamingDtos;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Devices;
|
||||
using MediaBrowser.Controller.Dlna;
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
using MediaBrowser.Controller.Entities.Movies;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Playlists;
|
||||
using MediaBrowser.Model.Dto;
|
||||
using MediaBrowser.Model.Querying;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
|
@ -51,7 +50,7 @@ namespace Jellyfin.Api.Controllers
|
|||
public ActionResult<QueryFiltersLegacy> GetQueryFiltersLegacy(
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes)
|
||||
{
|
||||
var user = userId.HasValue && !userId.Equals(Guid.Empty)
|
||||
|
@ -60,10 +59,10 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
BaseItem? item = null;
|
||||
if (includeItemTypes.Length != 1
|
||||
|| !(string.Equals(includeItemTypes[0], nameof(BoxSet), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], nameof(Playlist), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], nameof(Trailer), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], "Program", StringComparison.OrdinalIgnoreCase)))
|
||||
|| !(includeItemTypes[0] == BaseItemKind.BoxSet
|
||||
|| includeItemTypes[0] == BaseItemKind.Playlist
|
||||
|| includeItemTypes[0] == BaseItemKind.Trailer
|
||||
|| includeItemTypes[0] == BaseItemKind.Program))
|
||||
{
|
||||
item = _libraryManager.GetParentItem(parentId, user?.Id);
|
||||
}
|
||||
|
@ -72,7 +71,7 @@ namespace Jellyfin.Api.Controllers
|
|||
{
|
||||
User = user,
|
||||
MediaTypes = mediaTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
Recursive = true,
|
||||
EnableTotalRecordCount = false,
|
||||
DtoOptions = new DtoOptions
|
||||
|
@ -137,7 +136,7 @@ namespace Jellyfin.Api.Controllers
|
|||
public ActionResult<QueryFilters> GetQueryFilters(
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery] bool? isAiring,
|
||||
[FromQuery] bool? isMovie,
|
||||
[FromQuery] bool? isSports,
|
||||
|
@ -152,10 +151,10 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
BaseItem? parentItem = null;
|
||||
if (includeItemTypes.Length == 1
|
||||
&& (string.Equals(includeItemTypes[0], nameof(BoxSet), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], nameof(Playlist), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], nameof(Trailer), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], "Program", StringComparison.OrdinalIgnoreCase)))
|
||||
&& (includeItemTypes[0] == BaseItemKind.BoxSet
|
||||
|| includeItemTypes[0] == BaseItemKind.Playlist
|
||||
|| includeItemTypes[0] == BaseItemKind.Trailer
|
||||
|| includeItemTypes[0] == BaseItemKind.Program))
|
||||
{
|
||||
parentItem = null;
|
||||
}
|
||||
|
@ -167,7 +166,7 @@ namespace Jellyfin.Api.Controllers
|
|||
var filters = new QueryFilters();
|
||||
var genreQuery = new InternalItemsQuery(user)
|
||||
{
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
DtoOptions = new DtoOptions
|
||||
{
|
||||
Fields = Array.Empty<ItemFields>(),
|
||||
|
@ -192,10 +191,10 @@ namespace Jellyfin.Api.Controllers
|
|||
}
|
||||
|
||||
if (includeItemTypes.Length == 1
|
||||
&& (string.Equals(includeItemTypes[0], nameof(MusicAlbum), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], nameof(MusicVideo), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], nameof(MusicArtist), StringComparison.OrdinalIgnoreCase)
|
||||
|| string.Equals(includeItemTypes[0], nameof(Audio), StringComparison.OrdinalIgnoreCase)))
|
||||
&& (includeItemTypes[0] == BaseItemKind.MusicAlbum
|
||||
|| includeItemTypes[0] == BaseItemKind.MusicVideo
|
||||
|| includeItemTypes[0] == BaseItemKind.MusicArtist
|
||||
|| includeItemTypes[0] == BaseItemKind.Audio))
|
||||
{
|
||||
filters.Genres = _libraryManager.GetMusicGenres(genreQuery).Items.Select(i => new NameGuidPair
|
||||
{
|
||||
|
|
|
@ -6,6 +6,7 @@ using Jellyfin.Api.Extensions;
|
|||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -74,8 +75,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] string? searchTerm,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery] int? imageTypeLimit,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
|
||||
|
@ -96,8 +97,8 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
StartIndex = startIndex,
|
||||
Limit = limit,
|
||||
IsFavorite = isFavorite,
|
||||
|
|
|
@ -2,13 +2,11 @@ using System;
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
|
|
@ -87,6 +87,7 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
||||
[HttpPost("Users/{userId}/Images/{imageType}")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[AcceptsImageFile]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
|
||||
|
@ -133,6 +134,7 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
||||
[HttpPost("Users/{userId}/Images/{imageType}/{index}")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[AcceptsImageFile]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "imageType", Justification = "Imported from ServiceStack")]
|
||||
|
@ -312,6 +314,7 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
|
||||
[HttpPost("Items/{itemId}/Images/{imageType}")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[AcceptsImageFile]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
|
||||
|
@ -346,6 +349,7 @@ namespace Jellyfin.Api.Controllers
|
|||
/// <returns>A <see cref="NoContentResult"/> on success, or a <see cref="NotFoundResult"/> if item not found.</returns>
|
||||
[HttpPost("Items/{itemId}/Images/{imageType}/{imageIndex}")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[AcceptsImageFile]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "index", Justification = "Imported from ServiceStack")]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
|
|
|
@ -2,8 +2,6 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
|
@ -178,8 +177,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||
|
@ -233,8 +232,8 @@ namespace Jellyfin.Api.Controllers
|
|||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||
|
||||
if (includeItemTypes.Length == 1
|
||||
&& (includeItemTypes[0].Equals("Playlist", StringComparison.OrdinalIgnoreCase)
|
||||
|| includeItemTypes[0].Equals("BoxSet", StringComparison.OrdinalIgnoreCase)))
|
||||
&& (includeItemTypes[0] == BaseItemKind.Playlist
|
||||
|| includeItemTypes[0] == BaseItemKind.BoxSet))
|
||||
{
|
||||
parentId = null;
|
||||
}
|
||||
|
@ -251,7 +250,7 @@ namespace Jellyfin.Api.Controllers
|
|||
&& string.Equals(hasCollectionType.CollectionType, CollectionType.Playlists, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
recursive = true;
|
||||
includeItemTypes = new[] { "Playlist" };
|
||||
includeItemTypes = new[] { BaseItemKind.Playlist };
|
||||
}
|
||||
|
||||
var enabledChannels = user!.GetPreferenceValues<Guid>(PreferenceKind.EnabledChannels);
|
||||
|
@ -286,8 +285,8 @@ namespace Jellyfin.Api.Controllers
|
|||
{
|
||||
IsPlayed = isPlayed,
|
||||
MediaTypes = mediaTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
Recursive = recursive ?? false,
|
||||
OrderBy = RequestHelpers.GetOrderBy(sortBy, sortOrder),
|
||||
IsFavorite = isFavorite,
|
||||
|
@ -611,8 +610,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||
|
@ -773,8 +772,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] bool? enableUserData,
|
||||
[FromQuery] int? imageTypeLimit,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery] bool enableTotalRecordCount = true,
|
||||
[FromQuery] bool? enableImages = true)
|
||||
{
|
||||
|
@ -810,8 +809,8 @@ namespace Jellyfin.Api.Controllers
|
|||
CollapseBoxSetItems = false,
|
||||
EnableTotalRecordCount = enableTotalRecordCount,
|
||||
AncestorIds = ancestorIds,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
SearchTerm = searchTerm
|
||||
});
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ using System.Threading.Tasks;
|
|||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Api.Models.LibraryDtos;
|
||||
using Jellyfin.Data.Entities;
|
||||
|
|
|
@ -6,6 +6,7 @@ using Jellyfin.Api.Extensions;
|
|||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Entities.Audio;
|
||||
|
@ -74,8 +75,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] string? searchTerm,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery] int? imageTypeLimit,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
|
||||
|
@ -96,8 +97,8 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
StartIndex = startIndex,
|
||||
Limit = limit,
|
||||
IsFavorite = isFavorite,
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Constants;
|
||||
using MediaBrowser.Common.Json;
|
||||
using MediaBrowser.Common.Updates;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Model.Updates;
|
||||
|
|
|
@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Entities;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
|
|
|
@ -6,7 +6,6 @@ using System.Threading.Tasks;
|
|||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Api.Models.PlaylistDtos;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Mime;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
|
@ -300,9 +298,7 @@ namespace Jellyfin.Api.Controllers
|
|||
}
|
||||
|
||||
var imagePath = Path.Combine(plugin.Path, plugin.Manifest.ImagePath ?? string.Empty);
|
||||
if (((ServerConfiguration)_config.CommonConfiguration).DisablePluginImages
|
||||
|| plugin.Manifest.ImagePath == null
|
||||
|| !System.IO.File.Exists(imagePath))
|
||||
if (plugin.Manifest.ImagePath == null || !System.IO.File.Exists(imagePath))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
@ -83,8 +84,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] int? limit,
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery, Required] string searchTerm,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery] bool? isMovie,
|
||||
|
@ -109,8 +110,8 @@ namespace Jellyfin.Api.Controllers
|
|||
IncludeStudios = includeStudios,
|
||||
StartIndex = startIndex,
|
||||
UserId = userId ?? Guid.Empty,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
MediaTypes = mediaTypes,
|
||||
ParentId = parentId,
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ using Jellyfin.Api.Extensions;
|
|||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Entities;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
|
@ -73,8 +74,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] string? searchTerm,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery] bool? enableUserData,
|
||||
[FromQuery] int? imageTypeLimit,
|
||||
|
@ -96,8 +97,8 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
StartIndex = startIndex,
|
||||
Limit = limit,
|
||||
IsFavorite = isFavorite,
|
||||
|
|
|
@ -3,7 +3,6 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading;
|
||||
|
|
|
@ -5,7 +5,6 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Mime;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Constants;
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using MediaBrowser.Model.SyncPlay;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
|
|
@ -148,7 +148,7 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFilter[] filters,
|
||||
[FromQuery] bool? isFavorite,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||
|
@ -194,7 +194,7 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery] bool enableTotalRecordCount = true,
|
||||
[FromQuery] bool? enableImages = true)
|
||||
{
|
||||
var includeItemTypes = new[] { "Trailer" };
|
||||
var includeItemTypes = new[] { BaseItemKind.Trailer };
|
||||
|
||||
return _itemsController
|
||||
.GetItems(
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
|
|
|
@ -8,6 +8,7 @@ using Jellyfin.Api.Constants;
|
|||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
|
@ -269,7 +270,7 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromRoute, Required] Guid userId,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery] bool? isPlayed,
|
||||
[FromQuery] bool? enableImages,
|
||||
[FromQuery] int? imageTypeLimit,
|
||||
|
@ -296,7 +297,7 @@ namespace Jellyfin.Api.Controllers
|
|||
new LatestItemsQuery
|
||||
{
|
||||
GroupItems = groupItems,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
IsPlayed = isPlayed,
|
||||
Limit = limit,
|
||||
ParentId = parentId ?? Guid.Empty,
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.ComponentModel.DataAnnotations;
|
|||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Api.Models.UserViewDtos;
|
||||
using MediaBrowser.Controller.Dto;
|
||||
|
|
|
@ -12,7 +12,6 @@ using Jellyfin.Api.Helpers;
|
|||
using Jellyfin.Api.Models.PlaybackDtos;
|
||||
using Jellyfin.Api.Models.StreamingDtos;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Devices;
|
||||
using MediaBrowser.Controller.Dlna;
|
||||
|
|
|
@ -74,8 +74,8 @@ namespace Jellyfin.Api.Controllers
|
|||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] SortOrder[] sortOrder,
|
||||
[FromQuery] Guid? parentId,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ItemFields[] fields,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] excludeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] BaseItemKind[] includeItemTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] mediaTypes,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] string[] sortBy,
|
||||
[FromQuery] bool? enableUserData,
|
||||
|
@ -101,8 +101,8 @@ namespace Jellyfin.Api.Controllers
|
|||
|
||||
var query = new InternalItemsQuery(user)
|
||||
{
|
||||
ExcludeItemTypes = excludeItemTypes,
|
||||
IncludeItemTypes = includeItemTypes,
|
||||
ExcludeItemTypes = RequestHelpers.GetItemTypeStrings(excludeItemTypes),
|
||||
IncludeItemTypes = RequestHelpers.GetItemTypeStrings(includeItemTypes),
|
||||
MediaTypes = mediaTypes,
|
||||
DtoOptions = dtoOptions
|
||||
};
|
||||
|
@ -193,16 +193,17 @@ namespace Jellyfin.Api.Controllers
|
|||
return _dtoService.GetBaseItemDto(item, dtoOptions);
|
||||
}
|
||||
|
||||
private bool FilterItem(BaseItem f, IReadOnlyCollection<string> excludeItemTypes, IReadOnlyCollection<string> includeItemTypes, IReadOnlyCollection<string> mediaTypes)
|
||||
private bool FilterItem(BaseItem f, IReadOnlyCollection<BaseItemKind> excludeItemTypes, IReadOnlyCollection<BaseItemKind> includeItemTypes, IReadOnlyCollection<string> mediaTypes)
|
||||
{
|
||||
var baseItemKind = f.GetBaseItemKind();
|
||||
// Exclude item types
|
||||
if (excludeItemTypes.Count > 0 && excludeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase))
|
||||
if (excludeItemTypes.Count > 0 && excludeItemTypes.Contains(baseItemKind))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Include item types
|
||||
if (includeItemTypes.Count > 0 && !includeItemTypes.Contains(f.GetType().Name, StringComparer.OrdinalIgnoreCase))
|
||||
if (includeItemTypes.Count > 0 && !includeItemTypes.Contains(baseItemKind))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -129,5 +129,21 @@ namespace Jellyfin.Api.Helpers
|
|||
TotalRecordCount = result.TotalRecordCount
|
||||
};
|
||||
}
|
||||
|
||||
internal static string[] GetItemTypeStrings(IReadOnlyList<BaseItemKind> itemKinds)
|
||||
{
|
||||
if (itemKinds.Count == 0)
|
||||
{
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
var itemTypes = new string[itemKinds.Count];
|
||||
for (var i = 0; i < itemKinds.Count; i++)
|
||||
{
|
||||
itemTypes[i] = itemKinds[i].ToString();
|
||||
}
|
||||
|
||||
return itemTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<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="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>
|
||||
|
@ -38,4 +38,10 @@
|
|||
<CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>Jellyfin.Api.Tests</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
190
Jellyfin.Data/Enums/BaseItemKind.cs
Normal file
190
Jellyfin.Data/Enums/BaseItemKind.cs
Normal file
|
@ -0,0 +1,190 @@
|
|||
namespace Jellyfin.Data.Enums
|
||||
{
|
||||
/// <summary>
|
||||
/// The base item kind.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This enum is generated from all classes that inherit from <c>BaseItem</c>.
|
||||
/// </remarks>
|
||||
public enum BaseItemKind
|
||||
{
|
||||
/// <summary>
|
||||
/// Item is aggregate folder.
|
||||
/// </summary>
|
||||
AggregateFolder,
|
||||
|
||||
/// <summary>
|
||||
/// Item is audio.
|
||||
/// </summary>
|
||||
Audio,
|
||||
|
||||
/// <summary>
|
||||
/// Item is audio book.
|
||||
/// </summary>
|
||||
AudioBook,
|
||||
|
||||
/// <summary>
|
||||
/// Item is base plugin folder.
|
||||
/// </summary>
|
||||
BasePluginFolder,
|
||||
|
||||
/// <summary>
|
||||
/// Item is book.
|
||||
/// </summary>
|
||||
Book,
|
||||
|
||||
/// <summary>
|
||||
/// Item is box set.
|
||||
/// </summary>
|
||||
BoxSet,
|
||||
|
||||
/// <summary>
|
||||
/// Item is channel.
|
||||
/// </summary>
|
||||
Channel,
|
||||
|
||||
/// <summary>
|
||||
/// Item is channel folder item.
|
||||
/// </summary>
|
||||
ChannelFolderItem,
|
||||
|
||||
/// <summary>
|
||||
/// Item is collection folder.
|
||||
/// </summary>
|
||||
CollectionFolder,
|
||||
|
||||
/// <summary>
|
||||
/// Item is episode.
|
||||
/// </summary>
|
||||
Episode,
|
||||
|
||||
/// <summary>
|
||||
/// Item is folder.
|
||||
/// </summary>
|
||||
Folder,
|
||||
|
||||
/// <summary>
|
||||
/// Item is genre.
|
||||
/// </summary>
|
||||
Genre,
|
||||
|
||||
/// <summary>
|
||||
/// Item is manual playlists folder.
|
||||
/// </summary>
|
||||
ManualPlaylistsFolder,
|
||||
|
||||
/// <summary>
|
||||
/// Item is movie.
|
||||
/// </summary>
|
||||
Movie,
|
||||
|
||||
/// <summary>
|
||||
/// Item is music album.
|
||||
/// </summary>
|
||||
MusicAlbum,
|
||||
|
||||
/// <summary>
|
||||
/// Item is music artist.
|
||||
/// </summary>
|
||||
MusicArtist,
|
||||
|
||||
/// <summary>
|
||||
/// Item is music genre.
|
||||
/// </summary>
|
||||
MusicGenre,
|
||||
|
||||
/// <summary>
|
||||
/// Item is music video.
|
||||
/// </summary>
|
||||
MusicVideo,
|
||||
|
||||
/// <summary>
|
||||
/// Item is person.
|
||||
/// </summary>
|
||||
Person,
|
||||
|
||||
/// <summary>
|
||||
/// Item is photo.
|
||||
/// </summary>
|
||||
Photo,
|
||||
|
||||
/// <summary>
|
||||
/// Item is photo album.
|
||||
/// </summary>
|
||||
PhotoAlbum,
|
||||
|
||||
/// <summary>
|
||||
/// Item is playlist.
|
||||
/// </summary>
|
||||
Playlist,
|
||||
|
||||
/// <summary>
|
||||
/// Item is program
|
||||
/// </summary>
|
||||
Program,
|
||||
|
||||
/// <summary>
|
||||
/// Item is recording.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Manually added.
|
||||
/// </remarks>
|
||||
Recording,
|
||||
|
||||
/// <summary>
|
||||
/// Item is season.
|
||||
/// </summary>
|
||||
Season,
|
||||
|
||||
/// <summary>
|
||||
/// Item is series.
|
||||
/// </summary>
|
||||
Series,
|
||||
|
||||
/// <summary>
|
||||
/// Item is studio.
|
||||
/// </summary>
|
||||
Studio,
|
||||
|
||||
/// <summary>
|
||||
/// Item is trailer.
|
||||
/// </summary>
|
||||
Trailer,
|
||||
|
||||
/// <summary>
|
||||
/// Item is live tv channel.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Type is overridden.
|
||||
/// </remarks>
|
||||
TvChannel,
|
||||
|
||||
/// <summary>
|
||||
/// Item is live tv program.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Type is overridden.
|
||||
/// </remarks>
|
||||
TvProgram,
|
||||
|
||||
/// <summary>
|
||||
/// Item is user root folder.
|
||||
/// </summary>
|
||||
UserRootFolder,
|
||||
|
||||
/// <summary>
|
||||
/// Item is user view.
|
||||
/// </summary>
|
||||
UserView,
|
||||
|
||||
/// <summary>
|
||||
/// Item is video.
|
||||
/// </summary>
|
||||
Video,
|
||||
|
||||
/// <summary>
|
||||
/// Item is year.
|
||||
/// </summary>
|
||||
Year
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Data</PackageId>
|
||||
<VersionPrefix>10.7.0</VersionPrefix>
|
||||
<VersionPrefix>10.8.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
@ -41,8 +41,8 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -26,11 +26,11 @@
|
|||
|
||||
<ItemGroup>
|
||||
<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>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.2">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
|
|
@ -316,6 +316,7 @@ namespace Jellyfin.Server.Extensions
|
|||
|
||||
c.OperationFilter<SecurityRequirementsOperationFilter>();
|
||||
c.OperationFilter<FileResponseFilter>();
|
||||
c.OperationFilter<FileRequestFilter>();
|
||||
c.OperationFilter<ParameterObsoleteFilter>();
|
||||
c.DocumentFilter<WebsocketModelFilter>();
|
||||
});
|
||||
|
|
43
Jellyfin.Server/Filters/FileRequestFilter.cs
Normal file
43
Jellyfin.Server/Filters/FileRequestFilter.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
using System.Collections.Generic;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace Jellyfin.Server.Filters
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public class FileRequestFilter : IOperationFilter
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
foreach (var attribute in context.ApiDescription.ActionDescriptor.EndpointMetadata)
|
||||
{
|
||||
if (attribute is AcceptsFileAttribute acceptsFileAttribute)
|
||||
{
|
||||
operation.RequestBody = GetRequestBody(acceptsFileAttribute.GetContentTypes());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static OpenApiRequestBody GetRequestBody(IEnumerable<string> contentTypes)
|
||||
{
|
||||
var body = new OpenApiRequestBody();
|
||||
var mediaType = new OpenApiMediaType
|
||||
{
|
||||
Schema = new OpenApiSchema
|
||||
{
|
||||
Type = "string",
|
||||
Format = "binary"
|
||||
}
|
||||
};
|
||||
foreach (var contentType in contentTypes)
|
||||
{
|
||||
body.Content.Add(contentType, mediaType);
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,8 +40,8 @@
|
|||
<PackageReference Include="CommandLineParser" Version="2.8.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.Diagnostics.HealthChecks" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.3" />
|
||||
<PackageReference Include="prometheus-net" Version="4.1.1" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="4.1.1" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Common</PackageId>
|
||||
<VersionPrefix>10.7.0</VersionPrefix>
|
||||
<VersionPrefix>10.8.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -1998,6 +1998,11 @@ namespace MediaBrowser.Controller.Entities
|
|||
return GetType().Name;
|
||||
}
|
||||
|
||||
public BaseItemKind GetBaseItemKind()
|
||||
{
|
||||
return Enum.Parse<BaseItemKind>(GetClientTypeName());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the linked child.
|
||||
/// </summary>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Controller</PackageId>
|
||||
<VersionPrefix>10.7.0</VersionPrefix>
|
||||
<VersionPrefix>10.8.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</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>
|
||||
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>
|
||||
/// Extracts the audio image.
|
||||
/// </summary>
|
||||
|
|
|
@ -296,6 +296,38 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
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)
|
||||
{
|
||||
string codecstr = codec == Codec.Encoder ? "encoders" : "decoders";
|
||||
|
|
|
@ -295,6 +295,17 @@ namespace MediaBrowser.MediaEncoding.Encoder
|
|||
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)
|
||||
{
|
||||
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 = 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);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
|
|||
|
||||
subEvent.Text = string.Join(ParserValues.NewLine, multiline);
|
||||
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, "<(\\/?(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 EnableVppTonemapping { get; set; }
|
||||
|
||||
public string TonemappingAlgorithm { get; set; }
|
||||
|
||||
public string TonemappingRange { get; set; }
|
||||
|
@ -65,6 +67,8 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public bool EnableDecodingColorDepth10Vp9 { get; set; }
|
||||
|
||||
public bool EnableEnhancedNvdecDecoder { get; set; }
|
||||
|
||||
public bool EnableHardwareEncoding { 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.
|
||||
OpenclDevice = "0.0";
|
||||
EnableTonemapping = false;
|
||||
EnableVppTonemapping = false;
|
||||
TonemappingAlgorithm = "hable";
|
||||
TonemappingRange = "auto";
|
||||
TonemappingDesat = 0;
|
||||
|
@ -100,6 +105,7 @@ namespace MediaBrowser.Model.Configuration
|
|||
DeinterlaceMethod = "yadif";
|
||||
EnableDecodingColorDepth10Hevc = true;
|
||||
EnableDecodingColorDepth10Vp9 = true;
|
||||
EnableEnhancedNvdecDecoder = true;
|
||||
EnableHardwareEncoding = true;
|
||||
AllowHevcEncoding = true;
|
||||
EnableSubtitleExtraction = true;
|
||||
|
|
|
@ -418,8 +418,6 @@ namespace MediaBrowser.Model.Configuration
|
|||
|
||||
public PathSubstitution[] PathSubstitutions { get; set; } = Array.Empty<PathSubstitution>();
|
||||
|
||||
public bool EnableSimpleArtistDetection { get; set; } = false;
|
||||
|
||||
public string[] UninstalledPlugins { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
|
@ -461,10 +459,5 @@ namespace MediaBrowser.Model.Configuration
|
|||
/// Gets or sets a value indicating whether older plugins should automatically be deleted from the plugin folder.
|
||||
/// </summary>
|
||||
public bool RemoveOldPlugins { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether plugin image should be disabled.
|
||||
/// </summary>
|
||||
public bool DisablePluginImages { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Jellyfin.Data.Enums;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Entities;
|
||||
using MediaBrowser.Model.Library;
|
||||
|
@ -276,7 +277,7 @@ namespace MediaBrowser.Model.Dto
|
|||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string Type { get; set; }
|
||||
public BaseItemKind Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the people.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<PropertyGroup>
|
||||
<Authors>Jellyfin Contributors</Authors>
|
||||
<PackageId>Jellyfin.Model</PackageId>
|
||||
<VersionPrefix>10.7.0</VersionPrefix>
|
||||
<VersionPrefix>10.8.0</VersionPrefix>
|
||||
<RepositoryUrl>https://github.com/jellyfin/jellyfin</RepositoryUrl>
|
||||
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
|
||||
</PropertyGroup>
|
||||
|
|
|
@ -721,20 +721,6 @@ namespace MediaBrowser.XbmcMetadata.Parsers
|
|||
break;
|
||||
}
|
||||
|
||||
case "musicBrainzArtistID":
|
||||
{
|
||||
if (reader.IsEmptyElement)
|
||||
{
|
||||
reader.Read();
|
||||
break;
|
||||
}
|
||||
|
||||
var id = reader.ReadElementContentAsString();
|
||||
item.SetProviderId(MetadataProvider.MusicBrainzArtist.ToString(), id);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
string readerName = reader.Name;
|
||||
if (_validProviderIds.TryGetValue(readerName, out string? providerIdValue))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion("10.7.0")]
|
||||
[assembly: AssemblyFileVersion("10.7.0")]
|
||||
[assembly: AssemblyVersion("10.8.0")]
|
||||
[assembly: AssemblyFileVersion("10.8.0")]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
# We just wrap `build` so this is really it
|
||||
name: "jellyfin"
|
||||
version: "10.7.0"
|
||||
version: "10.8.0"
|
||||
packages:
|
||||
- debian.amd64
|
||||
- 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
|
||||
|
||||
* 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
|
||||
|
||||
Package: jellyfin
|
||||
Version: 10.7.0
|
||||
Version: 10.8.0
|
||||
Maintainer: Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
Depends: jellyfin-server, jellyfin-web
|
||||
Description: Provides the Jellyfin Free Software Media System
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -15,7 +15,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -16,7 +16,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -15,7 +15,7 @@ RUN apt-get update \
|
|||
|
||||
# Install dotnet repository
|
||||
# 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 \
|
||||
&& tar -xzf dotnet-sdk.tar.gz -C dotnet-sdk \
|
||||
&& ln -s $( pwd )/dotnet-sdk/dotnet /usr/bin/dotnet
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
%endif
|
||||
|
||||
Name: jellyfin
|
||||
Version: 10.7.0
|
||||
Version: 10.8.0
|
||||
Release: 1%{?dist}
|
||||
Summary: The Free Software Media System
|
||||
License: GPLv3
|
||||
|
@ -137,6 +137,8 @@ fi
|
|||
%systemd_postun_with_restart jellyfin.service
|
||||
|
||||
%changelog
|
||||
* Fri Dec 04 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- Forthcoming stable release
|
||||
* Mon Jul 27 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- Forthcoming stable release
|
||||
* Mon Mar 23 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
|
|
|
@ -6,11 +6,11 @@ using Xunit;
|
|||
|
||||
namespace Jellyfin.Api.Tests.Helpers
|
||||
{
|
||||
public class RequestHelpersTests
|
||||
public static class RequestHelpersTests
|
||||
{
|
||||
[Theory]
|
||||
[MemberData(nameof(GetOrderBy_Success_TestData))]
|
||||
public void GetOrderBy_Success(IReadOnlyList<string> sortBy, IReadOnlyList<SortOrder> requestedSortOrder, (string, SortOrder)[] expected)
|
||||
public static void GetOrderBy_Success(IReadOnlyList<string> sortBy, IReadOnlyList<SortOrder> requestedSortOrder, (string, SortOrder)[] expected)
|
||||
{
|
||||
Assert.Equal(expected, RequestHelpers.GetOrderBy(sortBy, requestedSortOrder));
|
||||
}
|
||||
|
@ -55,5 +55,35 @@ namespace Jellyfin.Api.Tests.Helpers
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GetItemTypeStrings_Empty_Empty()
|
||||
{
|
||||
Assert.Empty(RequestHelpers.GetItemTypeStrings(Array.Empty<BaseItemKind>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public static void GetItemTypeStrings_Valid_Success()
|
||||
{
|
||||
BaseItemKind[] input =
|
||||
{
|
||||
BaseItemKind.AggregateFolder,
|
||||
BaseItemKind.Audio,
|
||||
BaseItemKind.BasePluginFolder,
|
||||
BaseItemKind.CollectionFolder
|
||||
};
|
||||
|
||||
string[] expected =
|
||||
{
|
||||
"AggregateFolder",
|
||||
"Audio",
|
||||
"BasePluginFolder",
|
||||
"CollectionFolder"
|
||||
};
|
||||
|
||||
var res = RequestHelpers.GetItemTypeStrings(input);
|
||||
|
||||
Assert.Equal(expected, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<PackageReference Include="AutoFixture" Version="4.15.0" />
|
||||
<PackageReference Include="AutoFixture.AutoMoq" 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.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user