mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-01-20 01:58:18 +00:00
Compare commits
22 Commits
v10.7.0-rc
...
v10.7.0-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5a7478600 | ||
|
|
ed333dec43 | ||
|
|
c17c32f9dc | ||
|
|
5cc8ed6516 | ||
|
|
cdba6b3d35 | ||
|
|
fa7a8752a9 | ||
|
|
d129afa74e | ||
|
|
bc8a1d2276 | ||
|
|
147f9e1edf | ||
|
|
7796486511 | ||
|
|
ab5ae34595 | ||
|
|
81a17b803d | ||
|
|
cc6afb0971 | ||
|
|
d9a9a23a3c | ||
|
|
dd1fddf79c | ||
|
|
4df7522629 | ||
|
|
9c83a6cef9 | ||
|
|
910819c71c | ||
|
|
a0e047d560 | ||
|
|
34322ba491 | ||
|
|
801dd74ff6 | ||
|
|
129453214f |
@@ -193,6 +193,10 @@ jobs:
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
variables:
|
||||
- name: JellyfinVersion
|
||||
value: $[replace(variables['Build.SourceBranch'],'refs/tags/v','')]
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Use .NET 5.0 sdk'
|
||||
@@ -204,12 +208,19 @@ jobs:
|
||||
displayName: 'Build Stable Nuget packages'
|
||||
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v')
|
||||
inputs:
|
||||
command: 'pack'
|
||||
packagesToPack: 'Jellyfin.Data/Jellyfin.Data.csproj;MediaBrowser.Common/MediaBrowser.Common.csproj;MediaBrowser.Controller/MediaBrowser.Controller.csproj;MediaBrowser.Model/MediaBrowser.Model.csproj;Emby.Naming/Emby.Naming.csproj'
|
||||
versioningScheme: 'off'
|
||||
command: 'custom'
|
||||
projects: |
|
||||
Jellyfin.Data/Jellyfin.Data.csproj
|
||||
MediaBrowser.Common/MediaBrowser.Common.csproj
|
||||
MediaBrowser.Controller/MediaBrowser.Controller.csproj
|
||||
MediaBrowser.Model/MediaBrowser.Model.csproj
|
||||
Emby.Naming/Emby.Naming.csproj
|
||||
custom: 'pack'
|
||||
arguments: -o $(Build.ArtifactStagingDirectory) -p:Version=$(JellyfinVersion)
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: 'Build Unstable Nuget packages'
|
||||
condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master')
|
||||
inputs:
|
||||
command: 'custom'
|
||||
projects: |
|
||||
@@ -232,7 +243,7 @@ jobs:
|
||||
condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v')
|
||||
inputs:
|
||||
command: 'push'
|
||||
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg;$(Build.ArtifactStagingDirectory)/**/*.snupkg'
|
||||
packagesToPush: '$(Build.ArtifactStagingDirectory)/**/*.nupkg'
|
||||
nuGetFeedType: 'external'
|
||||
publishFeedCredentials: 'NugetOrg'
|
||||
allowPackageConflicts: true # This ignores an error if the version already exists
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
- name: Setup .NET Core
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: '5.0.100'
|
||||
dotnet-version: '5.0.x'
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
|
||||
@@ -141,6 +141,7 @@
|
||||
- [Pusta](https://github.com/pusta)
|
||||
- [nielsvanvelzen](https://github.com/nielsvanvelzen)
|
||||
- [skyfrk](https://github.com/skyfrk)
|
||||
- [ianjazz246](https://github.com/ianjazz246)
|
||||
|
||||
# Emby Contributors
|
||||
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace Emby.Dlna.Didl
|
||||
|
||||
using (StringWriter builder = new StringWriterWithEncoding(Encoding.UTF8))
|
||||
{
|
||||
// If this using are changed to single lines, then write.Flush needs to be appended before the return.
|
||||
using (var writer = XmlWriter.Create(builder, settings))
|
||||
{
|
||||
// writer.WriteStartDocument();
|
||||
|
||||
@@ -315,7 +315,7 @@ namespace Emby.Dlna.Main
|
||||
var uri = new UriBuilder(_appHost.GetSmartApiUrl(address.Address) + descriptorUri);
|
||||
// DLNA will only work over http, so we must reset to http:// : {port}
|
||||
uri.Scheme = "http://";
|
||||
uri.Port = _netConfig.PublicPort;
|
||||
uri.Port = _netConfig.HttpServerPortNumber;
|
||||
|
||||
var device = new SsdpRootDevice
|
||||
{
|
||||
|
||||
@@ -826,7 +826,7 @@ namespace Emby.Dlna.PlayTo
|
||||
return SendPlayCommand(data as PlayRequest, cancellationToken);
|
||||
}
|
||||
|
||||
if (name == SessionMessageType.PlayState)
|
||||
if (name == SessionMessageType.Playstate)
|
||||
{
|
||||
return SendPlaystateCommand(data as PlaystateRequest, cancellationToken);
|
||||
}
|
||||
@@ -896,16 +896,16 @@ namespace Emby.Dlna.PlayTo
|
||||
|
||||
var parts = url.Split('/');
|
||||
|
||||
for (var i = 0; i < parts.Length; i++)
|
||||
for (var i = 0; i < parts.Length - 1; i++)
|
||||
{
|
||||
var part = parts[i];
|
||||
|
||||
if (string.Equals(part, "audio", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(part, "videos", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (parts.Length > i + 1)
|
||||
if (Guid.TryParse(parts[i + 1], out var result))
|
||||
{
|
||||
return Guid.Parse(parts[i + 1]);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,7 +582,26 @@ namespace Emby.Server.Implementations.Dto
|
||||
{
|
||||
baseItemPerson.PrimaryImageTag = GetTagAndFillBlurhash(dto, entity, ImageType.Primary);
|
||||
baseItemPerson.Id = entity.Id.ToString("N", CultureInfo.InvariantCulture);
|
||||
baseItemPerson.ImageBlurHashes = dto.ImageBlurHashes;
|
||||
if (dto.ImageBlurHashes != null)
|
||||
{
|
||||
// Only add BlurHash for the person's image.
|
||||
baseItemPerson.ImageBlurHashes = new Dictionary<ImageType, Dictionary<string, string>>();
|
||||
foreach (var (imageType, blurHash) in dto.ImageBlurHashes)
|
||||
{
|
||||
if (blurHash != null)
|
||||
{
|
||||
baseItemPerson.ImageBlurHashes[imageType] = new Dictionary<string, string>();
|
||||
foreach (var (imageId, blurHashValue) in blurHash)
|
||||
{
|
||||
if (string.Equals(baseItemPerson.PrimaryImageTag, imageId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
baseItemPerson.ImageBlurHashes[imageType][imageId] = blurHashValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.Add(baseItemPerson);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,9 +582,7 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
public virtual IEnumerable<FileSystemMetadata> GetDirectories(string path, bool recursive = false)
|
||||
{
|
||||
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
||||
|
||||
return ToMetadata(new DirectoryInfo(path).EnumerateDirectories("*", searchOption));
|
||||
return ToMetadata(new DirectoryInfo(path).EnumerateDirectories("*", GetEnumerationOptions(recursive)));
|
||||
}
|
||||
|
||||
public virtual IEnumerable<FileSystemMetadata> GetFiles(string path, bool recursive = false)
|
||||
@@ -594,16 +592,16 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
public virtual IEnumerable<FileSystemMetadata> GetFiles(string path, IReadOnlyList<string> extensions, bool enableCaseSensitiveExtensions, bool recursive = false)
|
||||
{
|
||||
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
||||
var enumerationOptions = GetEnumerationOptions(recursive);
|
||||
|
||||
// On linux and osx the search pattern is case sensitive
|
||||
// If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method
|
||||
if ((enableCaseSensitiveExtensions || _isEnvironmentCaseInsensitive) && extensions != null && extensions.Count == 1)
|
||||
{
|
||||
return ToMetadata(new DirectoryInfo(path).EnumerateFiles("*" + extensions[0], searchOption));
|
||||
return ToMetadata(new DirectoryInfo(path).EnumerateFiles("*" + extensions[0], enumerationOptions));
|
||||
}
|
||||
|
||||
var files = new DirectoryInfo(path).EnumerateFiles("*", searchOption);
|
||||
var files = new DirectoryInfo(path).EnumerateFiles("*", enumerationOptions);
|
||||
|
||||
if (extensions != null && extensions.Count > 0)
|
||||
{
|
||||
@@ -625,10 +623,10 @@ namespace Emby.Server.Implementations.IO
|
||||
public virtual IEnumerable<FileSystemMetadata> GetFileSystemEntries(string path, bool recursive = false)
|
||||
{
|
||||
var directoryInfo = new DirectoryInfo(path);
|
||||
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
||||
var enumerationOptions = GetEnumerationOptions(recursive);
|
||||
|
||||
return ToMetadata(directoryInfo.EnumerateDirectories("*", searchOption))
|
||||
.Concat(ToMetadata(directoryInfo.EnumerateFiles("*", searchOption)));
|
||||
return ToMetadata(directoryInfo.EnumerateDirectories("*", enumerationOptions))
|
||||
.Concat(ToMetadata(directoryInfo.EnumerateFiles("*", enumerationOptions)));
|
||||
}
|
||||
|
||||
private IEnumerable<FileSystemMetadata> ToMetadata(IEnumerable<FileSystemInfo> infos)
|
||||
@@ -638,8 +636,7 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
public virtual IEnumerable<string> GetDirectoryPaths(string path, bool recursive = false)
|
||||
{
|
||||
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
||||
return Directory.EnumerateDirectories(path, "*", searchOption);
|
||||
return Directory.EnumerateDirectories(path, "*", GetEnumerationOptions(recursive));
|
||||
}
|
||||
|
||||
public virtual IEnumerable<string> GetFilePaths(string path, bool recursive = false)
|
||||
@@ -649,16 +646,16 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
public virtual IEnumerable<string> GetFilePaths(string path, string[] extensions, bool enableCaseSensitiveExtensions, bool recursive = false)
|
||||
{
|
||||
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
||||
var enumerationOptions = GetEnumerationOptions(recursive);
|
||||
|
||||
// On linux and osx the search pattern is case sensitive
|
||||
// If we're OK with case-sensitivity, and we're only filtering for one extension, then use the native method
|
||||
if ((enableCaseSensitiveExtensions || _isEnvironmentCaseInsensitive) && extensions != null && extensions.Length == 1)
|
||||
{
|
||||
return Directory.EnumerateFiles(path, "*" + extensions[0], searchOption);
|
||||
return Directory.EnumerateFiles(path, "*" + extensions[0], enumerationOptions);
|
||||
}
|
||||
|
||||
var files = Directory.EnumerateFiles(path, "*", searchOption);
|
||||
var files = Directory.EnumerateFiles(path, "*", enumerationOptions);
|
||||
|
||||
if (extensions != null && extensions.Length > 0)
|
||||
{
|
||||
@@ -679,8 +676,16 @@ namespace Emby.Server.Implementations.IO
|
||||
|
||||
public virtual IEnumerable<string> GetFileSystemEntryPaths(string path, bool recursive = false)
|
||||
{
|
||||
var searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
|
||||
return Directory.EnumerateFileSystemEntries(path, "*", searchOption);
|
||||
return Directory.EnumerateFileSystemEntries(path, "*", GetEnumerationOptions(recursive));
|
||||
}
|
||||
|
||||
private EnumerationOptions GetEnumerationOptions(bool recursive)
|
||||
{
|
||||
return new EnumerationOptions
|
||||
{
|
||||
RecurseSubdirectories = recursive,
|
||||
IgnoreInaccessible = true
|
||||
};
|
||||
}
|
||||
|
||||
private static void RunProcess(string path, string args, string workingDirectory)
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||
/// Gets the priority.
|
||||
/// </summary>
|
||||
/// <value>The priority.</value>
|
||||
public override ResolverPriority Priority => ResolverPriority.Fourth;
|
||||
public override ResolverPriority Priority => ResolverPriority.Fifth;
|
||||
|
||||
public MultiItemResolverResult ResolveMultiple(
|
||||
Folder parent,
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
|
||||
/// Gets the priority.
|
||||
/// </summary>
|
||||
/// <value>The priority.</value>
|
||||
public override ResolverPriority Priority => ResolverPriority.Second;
|
||||
public override ResolverPriority Priority => ResolverPriority.Third;
|
||||
|
||||
/// <summary>
|
||||
/// Resolves the specified args.
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
|
||||
/// Gets the priority.
|
||||
/// </summary>
|
||||
/// <value>The priority.</value>
|
||||
public override ResolverPriority Priority => ResolverPriority.Third;
|
||||
public override ResolverPriority Priority => ResolverPriority.Fourth;
|
||||
|
||||
/// <inheritdoc />
|
||||
public MultiItemResolverResult ResolveMultiple(
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||
}
|
||||
|
||||
// It's a directory-based playlist if the directory contains a playlist file
|
||||
var filePaths = Directory.EnumerateFiles(args.Path);
|
||||
var filePaths = Directory.EnumerateFiles(args.Path, "*", new EnumerationOptions { IgnoreInaccessible = true });
|
||||
if (filePaths.Any(f => f.EndsWith(PlaylistXmlSaver.DefaultPlaylistFilename, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
return new Playlist
|
||||
|
||||
@@ -77,6 +77,8 @@ chb|||Chibcha|chibcha
|
||||
che||ce|Chechen|tchétchène
|
||||
chg|||Chagatai|djaghataï
|
||||
chi|zho|zh|Chinese|chinois
|
||||
chi|zho|zh-tw|Chinese; Traditional|chinois
|
||||
chi|zho|zh-hk|Chinese; Hong Kong|chinois
|
||||
chk|||Chuukese|chuuk
|
||||
chm|||Mari|mari
|
||||
chn|||Chinook jargon|chinook, jargon
|
||||
|
||||
@@ -374,7 +374,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||
private LocalPlugin? GetPluginByAssembly(Assembly assembly)
|
||||
{
|
||||
// Find which plugin it is by the path.
|
||||
return _plugins.FirstOrDefault(p => string.Equals(p.Path, Path.GetDirectoryName(assembly.Location), StringComparison.Ordinal));
|
||||
return _plugins.FirstOrDefault(p => p.DllFiles.Contains(assembly.Location, StringComparer.Ordinal));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -421,15 +421,17 @@ namespace Emby.Server.Implementations.Plugins
|
||||
{
|
||||
plugin.Instance = instance;
|
||||
var manifest = plugin.Manifest;
|
||||
var pluginStr = plugin.Instance.Version.ToString();
|
||||
var pluginStr = instance.Version.ToString();
|
||||
bool changed = false;
|
||||
if (string.Equals(manifest.Version, pluginStr, StringComparison.Ordinal))
|
||||
if (string.Equals(manifest.Version, pluginStr, StringComparison.Ordinal)
|
||||
|| manifest.Id != instance.Id)
|
||||
{
|
||||
// If a plugin without a manifest failed to load due to an external issue (eg config),
|
||||
// this updates the manifest to the actual plugin values.
|
||||
manifest.Version = pluginStr;
|
||||
manifest.Name = plugin.Instance.Name;
|
||||
manifest.Description = plugin.Instance.Description;
|
||||
manifest.Id = plugin.Instance.Id;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
@@ -559,7 +561,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||
// Auto-create a plugin manifest, so we can disable it, if it fails to load.
|
||||
manifest = new PluginManifest
|
||||
{
|
||||
Status = PluginStatus.Restart,
|
||||
Status = PluginStatus.Active,
|
||||
Name = metafile,
|
||||
AutoUpdate = false,
|
||||
Id = metafile.GetMD5(),
|
||||
|
||||
@@ -80,10 +80,11 @@ namespace Emby.Server.Implementations.ScheduledTasks.Tasks
|
||||
// Delete log files more than n days old
|
||||
var minDateModified = DateTime.UtcNow.AddDays(-_configurationManager.CommonConfiguration.LogFileRetentionDays);
|
||||
|
||||
// Only delete the .txt log files, the *.log files created by serilog get managed by itself
|
||||
var filesToDelete = _fileSystem.GetFiles(_configurationManager.CommonApplicationPaths.LogDirectoryPath, new[] { ".txt" }, true, true)
|
||||
.Where(f => _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
|
||||
.ToList();
|
||||
// Only delete files that serilog doesn't manage (anything that doesn't start with 'log_'
|
||||
var filesToDelete = _fileSystem.GetFiles(_configurationManager.CommonApplicationPaths.LogDirectoryPath, true)
|
||||
.Where(f => !f.Name.StartsWith("log_", StringComparison.Ordinal)
|
||||
&& _fileSystem.GetLastWriteTimeUtc(f) < minDateModified)
|
||||
.ToList();
|
||||
|
||||
var index = 0;
|
||||
|
||||
|
||||
@@ -1310,7 +1310,7 @@ namespace Emby.Server.Implementations.Session
|
||||
}
|
||||
}
|
||||
|
||||
return SendMessageToSession(session, SessionMessageType.PlayState, command, cancellationToken);
|
||||
return SendMessageToSession(session, SessionMessageType.Playstate, command, cancellationToken);
|
||||
}
|
||||
|
||||
private static void AssertCanControl(SessionInfo session, SessionInfo controllingSession)
|
||||
|
||||
@@ -143,10 +143,31 @@ namespace Emby.Server.Implementations.TV
|
||||
var allNextUp = seriesKeys
|
||||
.Select(i => GetNextUp(i, currentUser, dtoOptions));
|
||||
|
||||
// If viewing all next up for all series, remove first episodes
|
||||
// But if that returns empty, keep those first episodes (avoid completely empty view)
|
||||
var alwaysEnableFirstEpisode = !string.IsNullOrEmpty(request.SeriesId);
|
||||
var anyFound = false;
|
||||
|
||||
return allNextUp
|
||||
.Where(i =>
|
||||
{
|
||||
return i.Item1 != DateTime.MinValue;
|
||||
if (request.DisableFirstEpisode)
|
||||
{
|
||||
return i.Item1 != DateTime.MinValue;
|
||||
}
|
||||
|
||||
if (alwaysEnableFirstEpisode || i.Item1 != DateTime.MinValue)
|
||||
{
|
||||
anyFound = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!anyFound && i.Item1 == DateTime.MinValue)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
})
|
||||
.Select(i => i.Item2())
|
||||
.Where(i => i != null);
|
||||
|
||||
12
Jellyfin.Api/Attributes/ParameterObsoleteAttribute.cs
Normal file
12
Jellyfin.Api/Attributes/ParameterObsoleteAttribute.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
namespace Jellyfin.Api.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute to mark a parameter as obsolete.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
public class ParameterObsoleteAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,7 @@ namespace Jellyfin.Api.Controllers
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For backwards compatibility parameters can be sent via Query or Body, with Query having higher precedence.
|
||||
/// Query parameters are obsolete.
|
||||
/// </remarks>
|
||||
/// <param name="itemId">The item id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
@@ -106,20 +107,20 @@ namespace Jellyfin.Api.Controllers
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<PlaybackInfoResponse>> GetPostedPlaybackInfo(
|
||||
[FromRoute, Required] Guid itemId,
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] int? maxStreamingBitrate,
|
||||
[FromQuery] long? startTimeTicks,
|
||||
[FromQuery] int? audioStreamIndex,
|
||||
[FromQuery] int? subtitleStreamIndex,
|
||||
[FromQuery] int? maxAudioChannels,
|
||||
[FromQuery] string? mediaSourceId,
|
||||
[FromQuery] string? liveStreamId,
|
||||
[FromQuery] bool? autoOpenLiveStream,
|
||||
[FromQuery] bool? enableDirectPlay,
|
||||
[FromQuery] bool? enableDirectStream,
|
||||
[FromQuery] bool? enableTranscoding,
|
||||
[FromQuery] bool? allowVideoStreamCopy,
|
||||
[FromQuery] bool? allowAudioStreamCopy,
|
||||
[FromQuery, ParameterObsolete] Guid? userId,
|
||||
[FromQuery, ParameterObsolete] int? maxStreamingBitrate,
|
||||
[FromQuery, ParameterObsolete] long? startTimeTicks,
|
||||
[FromQuery, ParameterObsolete] int? audioStreamIndex,
|
||||
[FromQuery, ParameterObsolete] int? subtitleStreamIndex,
|
||||
[FromQuery, ParameterObsolete] int? maxAudioChannels,
|
||||
[FromQuery, ParameterObsolete] string? mediaSourceId,
|
||||
[FromQuery, ParameterObsolete] string? liveStreamId,
|
||||
[FromQuery, ParameterObsolete] bool? autoOpenLiveStream,
|
||||
[FromQuery, ParameterObsolete] bool? enableDirectPlay,
|
||||
[FromQuery, ParameterObsolete] bool? enableDirectStream,
|
||||
[FromQuery, ParameterObsolete] bool? enableTranscoding,
|
||||
[FromQuery, ParameterObsolete] bool? allowVideoStreamCopy,
|
||||
[FromQuery, ParameterObsolete] bool? allowAudioStreamCopy,
|
||||
[FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] PlaybackInfoDto? playbackInfoDto)
|
||||
{
|
||||
var authInfo = _authContext.GetAuthorizationInfo(Request);
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
@@ -57,6 +58,7 @@ namespace Jellyfin.Api.Controllers
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// For backwards compatibility parameters can be sent via Query or Body, with Query having higher precedence.
|
||||
/// Query parameters are obsolete.
|
||||
/// </remarks>
|
||||
/// <param name="name">The playlist name.</param>
|
||||
/// <param name="ids">The item ids.</param>
|
||||
@@ -70,10 +72,10 @@ namespace Jellyfin.Api.Controllers
|
||||
[HttpPost]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult<PlaylistCreationResult>> CreatePlaylist(
|
||||
[FromQuery] string? name,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] IReadOnlyList<Guid> ids,
|
||||
[FromQuery] Guid? userId,
|
||||
[FromQuery] string? mediaType,
|
||||
[FromQuery, ParameterObsolete] string? name,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder)), ParameterObsolete] IReadOnlyList<Guid> ids,
|
||||
[FromQuery, ParameterObsolete] Guid? userId,
|
||||
[FromQuery, ParameterObsolete] string? mediaType,
|
||||
[FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] CreatePlaylistDto? createPlaylistRequest)
|
||||
{
|
||||
if (ids.Count == 0)
|
||||
|
||||
@@ -371,6 +371,7 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <response code="204">Subtitle uploaded.</response>
|
||||
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
||||
[HttpPost("Videos/{itemId}/Subtitles")]
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<ActionResult> UploadSubtitle(
|
||||
[FromRoute, Required] Guid itemId,
|
||||
|
||||
@@ -67,6 +67,7 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <param name="enableImageTypes">Optional. The image types to include in the output.</param>
|
||||
/// <param name="enableUserData">Optional. Include user data.</param>
|
||||
/// <param name="enableTotalRecordCount">Whether to enable the total records count. Defaults to true.</param>
|
||||
/// <param name="disableFirstEpisode">Whether to disable sending the first episode in a series as next up.</param>
|
||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the next up episodes.</returns>
|
||||
[HttpGet("NextUp")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
@@ -81,7 +82,8 @@ namespace Jellyfin.Api.Controllers
|
||||
[FromQuery] int? imageTypeLimit,
|
||||
[FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] ImageType[] enableImageTypes,
|
||||
[FromQuery] bool? enableUserData,
|
||||
[FromQuery] bool enableTotalRecordCount = true)
|
||||
[FromQuery] bool enableTotalRecordCount = true,
|
||||
[FromQuery] bool disableFirstEpisode = false)
|
||||
{
|
||||
var options = new DtoOptions { Fields = fields }
|
||||
.AddClientFields(Request)
|
||||
@@ -95,7 +97,8 @@ namespace Jellyfin.Api.Controllers
|
||||
SeriesId = seriesId,
|
||||
StartIndex = startIndex,
|
||||
UserId = userId ?? Guid.Empty,
|
||||
EnableTotalRecordCount = enableTotalRecordCount
|
||||
EnableTotalRecordCount = enableTotalRecordCount,
|
||||
DisableFirstEpisode = disableFirstEpisode
|
||||
},
|
||||
options);
|
||||
|
||||
@@ -267,7 +270,7 @@ namespace Jellyfin.Api.Controllers
|
||||
if (startItemId.HasValue)
|
||||
{
|
||||
episodes = episodes
|
||||
.SkipWhile(i => startItemId.Value.Equals(i.Id))
|
||||
.SkipWhile(i => !startItemId.Value.Equals(i.Id))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Jellyfin.Api.ModelBinders
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
_logger.LogWarning(e, "Error converting value.");
|
||||
_logger.LogDebug(e, "Error converting value.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace Jellyfin.Api.ModelBinders
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
_logger.LogWarning(e, "Error converting value.");
|
||||
_logger.LogDebug(e, "Error converting value.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Jellyfin.Api.ModelBinders
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
_logger.LogWarning(e, "Error converting value.");
|
||||
_logger.LogDebug(e, "Error converting value.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -224,7 +224,7 @@ namespace Jellyfin.Networking.Configuration
|
||||
public string[] LocalNetworkAddresses { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the known proxies.
|
||||
/// Gets or sets the known proxies. If the proxy is a network, it's added to the KnownNetworks.
|
||||
/// </summary>
|
||||
public string[] KnownProxies { get; set; } = Array.Empty<string>();
|
||||
}
|
||||
|
||||
@@ -387,7 +387,7 @@ namespace Jellyfin.Networking.Manager
|
||||
// Get the first LAN interface address that isn't a loopback.
|
||||
var interfaces = CreateCollection(_interfaceAddresses
|
||||
.Exclude(_bindExclusions)
|
||||
.Where(p => IsInLocalNetwork(p))
|
||||
.Where(IsInLocalNetwork)
|
||||
.OrderBy(p => p.Tag));
|
||||
|
||||
if (interfaces.Count > 0)
|
||||
@@ -591,7 +591,7 @@ namespace Jellyfin.Networking.Manager
|
||||
else // Used in testing only.
|
||||
{
|
||||
// Format is <IPAddress>,<Index>,<Name>: <next interface>. Set index to -ve to simulate a gateway.
|
||||
var interfaceList = MockNetworkSettings.Split(':');
|
||||
var interfaceList = MockNetworkSettings.Split('|');
|
||||
foreach (var details in interfaceList)
|
||||
{
|
||||
var parts = details.Split(',');
|
||||
|
||||
@@ -25,11 +25,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Linq.Async" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.1">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.1">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Reflection;
|
||||
using Emby.Server.Implementations;
|
||||
using Jellyfin.Api.Auth;
|
||||
@@ -20,6 +21,7 @@ using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Controllers;
|
||||
using Jellyfin.Api.ModelBinders;
|
||||
using Jellyfin.Data.Enums;
|
||||
using Jellyfin.Networking.Configuration;
|
||||
using Jellyfin.Server.Configuration;
|
||||
using Jellyfin.Server.Filters;
|
||||
using Jellyfin.Server.Formatters;
|
||||
@@ -174,30 +176,33 @@ namespace Jellyfin.Server.Extensions
|
||||
/// </summary>
|
||||
/// <param name="serviceCollection">The service collection.</param>
|
||||
/// <param name="pluginAssemblies">An IEnumerable containing all plugin assemblies with API controllers.</param>
|
||||
/// <param name="knownProxies">A list of all known proxies to trust for X-Forwarded-For.</param>
|
||||
/// <param name="config">The <see cref="NetworkConfiguration"/>.</param>
|
||||
/// <returns>The MVC builder.</returns>
|
||||
public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable<Assembly> pluginAssemblies, IReadOnlyList<string> knownProxies)
|
||||
public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable<Assembly> pluginAssemblies, NetworkConfiguration config)
|
||||
{
|
||||
IMvcBuilder mvcBuilder = serviceCollection
|
||||
.AddCors()
|
||||
.AddTransient<ICorsPolicyProvider, CorsPolicyProvider>()
|
||||
.Configure<ForwardedHeadersOptions>(options =>
|
||||
{
|
||||
// https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs
|
||||
// Enable debug logging on Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware to help investigate issues.
|
||||
|
||||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
|
||||
if (knownProxies.Count == 0)
|
||||
if (config.KnownProxies.Length == 0)
|
||||
{
|
||||
options.KnownNetworks.Clear();
|
||||
options.KnownProxies.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < knownProxies.Count; i++)
|
||||
{
|
||||
if (IPHost.TryParse(knownProxies[i], out var host))
|
||||
{
|
||||
options.KnownProxies.Add(host.Address);
|
||||
}
|
||||
}
|
||||
AddProxyAddresses(config, config.KnownProxies, options);
|
||||
}
|
||||
|
||||
// Only set forward limit if we have some known proxies or some known networks.
|
||||
if (options.KnownProxies.Count != 0 || options.KnownNetworks.Count != 0)
|
||||
{
|
||||
options.ForwardLimit = null;
|
||||
}
|
||||
})
|
||||
.AddMvc(opts =>
|
||||
@@ -308,10 +313,60 @@ namespace Jellyfin.Server.Extensions
|
||||
|
||||
c.OperationFilter<SecurityRequirementsOperationFilter>();
|
||||
c.OperationFilter<FileResponseFilter>();
|
||||
c.OperationFilter<ParameterObsoleteFilter>();
|
||||
c.DocumentFilter<WebsocketModelFilter>();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up the proxy configuration based on the addresses in <paramref name="allowedProxies"/>.
|
||||
/// </summary>
|
||||
/// <param name="config">The <see cref="NetworkConfiguration"/> containing the config settings.</param>
|
||||
/// <param name="allowedProxies">The string array to parse.</param>
|
||||
/// <param name="options">The <see cref="ForwardedHeadersOptions"/> instance.</param>
|
||||
internal static void AddProxyAddresses(NetworkConfiguration config, string[] allowedProxies, ForwardedHeadersOptions options)
|
||||
{
|
||||
for (var i = 0; i < allowedProxies.Length; i++)
|
||||
{
|
||||
if (IPNetAddress.TryParse(allowedProxies[i], out var addr))
|
||||
{
|
||||
AddIpAddress(config, options, addr.Address, addr.PrefixLength);
|
||||
}
|
||||
else if (IPHost.TryParse(allowedProxies[i], out var host))
|
||||
{
|
||||
foreach (var address in host.GetAddresses())
|
||||
{
|
||||
AddIpAddress(config, options, addr.Address, addr.PrefixLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddIpAddress(NetworkConfiguration config, ForwardedHeadersOptions options, IPAddress addr, int prefixLength)
|
||||
{
|
||||
if ((!config.EnableIPV4 && addr.AddressFamily == AddressFamily.InterNetwork) || (!config.EnableIPV6 && addr.AddressFamily == AddressFamily.InterNetworkV6))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// In order for dual-mode sockets to be used, IP6 has to be enabled in JF and an interface has to have an IP6 address.
|
||||
if (addr.AddressFamily == AddressFamily.InterNetwork && config.EnableIPV6)
|
||||
{
|
||||
// If the server is using dual-mode sockets, IPv4 addresses are supplied in an IPv6 format.
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0 .
|
||||
addr = addr.MapToIPv6();
|
||||
}
|
||||
|
||||
if (prefixLength == 32)
|
||||
{
|
||||
options.KnownProxies.Add(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
options.KnownNetworks.Add(new IPNetwork(addr, prefixLength));
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddSwaggerTypeMappings(this SwaggerGenOptions options)
|
||||
{
|
||||
/*
|
||||
|
||||
37
Jellyfin.Server/Filters/ParameterObsoleteFilter.cs
Normal file
37
Jellyfin.Server/Filters/ParameterObsoleteFilter.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Jellyfin.Api.Attributes;
|
||||
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||
|
||||
namespace Jellyfin.Server.Filters
|
||||
{
|
||||
/// <summary>
|
||||
/// Mark parameter as deprecated if it has the <see cref="ParameterObsoleteAttribute"/>.
|
||||
/// </summary>
|
||||
public class ParameterObsoleteFilter : IOperationFilter
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||
{
|
||||
foreach (var parameterDescription in context.ApiDescription.ParameterDescriptions)
|
||||
{
|
||||
if (parameterDescription
|
||||
.CustomAttributes()
|
||||
.OfType<ParameterObsoleteAttribute>()
|
||||
.Any())
|
||||
{
|
||||
foreach (var parameter in operation.Parameters)
|
||||
{
|
||||
if (parameter.Name.Equals(parameterDescription.Name, StringComparison.Ordinal))
|
||||
{
|
||||
parameter.Deprecated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="5.0.2" />
|
||||
<PackageReference Include="prometheus-net" Version="4.0.0" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="4.0.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
@@ -19,3 +20,5 @@ using System.Runtime.InteropServices;
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
[assembly: InternalsVisibleTo("Jellyfin.Api.Tests")]
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Jellyfin.Server
|
||||
{
|
||||
options.HttpsPort = _serverApplicationHost.HttpsPort;
|
||||
});
|
||||
services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.GetNetworkConfiguration().KnownProxies);
|
||||
services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.GetNetworkConfiguration());
|
||||
|
||||
services.AddJellyfinApiSwagger();
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace MediaBrowser.Common.Json.Converters
|
||||
{
|
||||
// TODO log when upgraded to .Net6
|
||||
// https://github.com/dotnet/runtime/issues/42975
|
||||
// _logger.LogWarning(e, "Error converting value.");
|
||||
// _logger.LogDebug(e, "Error converting value.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace MediaBrowser.Common.Json.Converters
|
||||
{
|
||||
// TODO log when upgraded to .Net6
|
||||
// https://github.com/dotnet/runtime/issues/42975
|
||||
// _logger.LogWarning(e, "Error converting value.");
|
||||
// _logger.LogDebug(e, "Error converting value.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,14 @@ namespace MediaBrowser.Controller.Resolvers
|
||||
/// </summary>
|
||||
Fourth = 4,
|
||||
|
||||
/// <summary>
|
||||
/// The Fifth.
|
||||
/// </summary>
|
||||
Fifth = 5,
|
||||
|
||||
/// <summary>
|
||||
/// The last.
|
||||
/// </summary>
|
||||
Last = 5
|
||||
Last = 6
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="System.Globalization" Version="4.3.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="5.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -64,10 +64,16 @@ namespace MediaBrowser.Model.Querying
|
||||
|
||||
public bool EnableTotalRecordCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether do disable sending first episode as next up.
|
||||
/// </summary>
|
||||
public bool DisableFirstEpisode { get; set; }
|
||||
|
||||
public NextUpQuery()
|
||||
{
|
||||
EnableImageTypes = Array.Empty<ImageType>();
|
||||
EnableTotalRecordCount = true;
|
||||
DisableFirstEpisode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace MediaBrowser.Model.Session
|
||||
Play,
|
||||
SyncPlayCommand,
|
||||
SyncPlayGroupUpdate,
|
||||
PlayState,
|
||||
Playstate,
|
||||
RestartRequired,
|
||||
ServerShuttingDown,
|
||||
ServerRestarting,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
# We just wrap `build` so this is really it
|
||||
name: "jellyfin"
|
||||
version: "10.7.0~rc2"
|
||||
version: "10.7.0~rc3"
|
||||
packages:
|
||||
- debian.amd64
|
||||
- debian.arm64
|
||||
|
||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
||||
jellyfin-server (10.7.0~rc3) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.7.0-rc3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.7.0-rc3
|
||||
|
||||
-- Jellyfin Packaging Team <packaging@jellyfin.org> Sat, 23 Jan 2021 15:49:02 -0500
|
||||
|
||||
jellyfin-server (10.7.0~rc2) unstable; urgency=medium
|
||||
|
||||
* New upstream version 10.7.0-rc2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.7.0-rc2
|
||||
|
||||
@@ -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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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/a0487784-534a-4912-a4dd-017382083865/be16057043a8f7b6f08c902dc48dd677/dotnet-sdk-5.0.101-linux-x64.tar.gz -O dotnet-sdk.tar.gz \
|
||||
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 \
|
||||
&& 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~rc2
|
||||
Version: 10.7.0~rc3
|
||||
Release: 1%{?dist}
|
||||
Summary: The Free Software Media System
|
||||
License: GPLv3
|
||||
@@ -28,7 +28,7 @@ BuildRequires: libcurl-devel, fontconfig-devel, freetype-devel, openssl-devel,
|
||||
# COPR @dotnet-sig/dotnet or
|
||||
# https://packages.microsoft.com/rhel/7/prod/
|
||||
BuildRequires: dotnet-runtime-5.0, dotnet-sdk-5.0
|
||||
Requires: %{name}-server = %{version}-%{release}, %{name}-web >= 10.6, %{name}-web < 10.7
|
||||
Requires: %{name}-server = %{version}-%{release}, %{name}-web = %{version}-%{release}
|
||||
# Disable Automatic Dependency Processing
|
||||
AutoReqProv: no
|
||||
|
||||
@@ -137,6 +137,8 @@ fi
|
||||
%systemd_postun_with_restart jellyfin.service
|
||||
|
||||
%changelog
|
||||
* Sat Jan 23 2021 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.7.0-rc3; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.7.0-rc3
|
||||
* Thu Dec 31 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
- New upstream version 10.7.0-rc2; release changelog at https://github.com/jellyfin/jellyfin/releases/tag/v10.7.0-rc2
|
||||
* Fri Dec 04 2020 Jellyfin Packaging Team <packaging@jellyfin.org>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<PackageReference Include="AutoFixture" Version="4.14.0" />
|
||||
<PackageReference Include="AutoFixture.AutoMoq" Version="4.14.0" />
|
||||
<PackageReference Include="AutoFixture.Xunit2" Version="4.14.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="5.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
|
||||
88
tests/Jellyfin.Api.Tests/ParseNetworkTests.cs
Normal file
88
tests/Jellyfin.Api.Tests/ParseNetworkTests.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using Jellyfin.Networking.Configuration;
|
||||
using Jellyfin.Networking.Manager;
|
||||
using Jellyfin.Server.Extensions;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Api.Tests
|
||||
{
|
||||
public class ParseNetworkTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Order of the result has always got to be hosts, then networks.
|
||||
/// </summary>
|
||||
/// <param name="ip4">IP4 enabled.</param>
|
||||
/// <param name="ip6">IP6 enabled.</param>
|
||||
/// <param name="hostList">List to parse.</param>
|
||||
/// <param name="match">What it should match.</param>
|
||||
[Theory]
|
||||
// [InlineData(true, true, "192.168.0.0/16,www.yahoo.co.uk", "::ffff:212.82.100.150,::ffff:192.168.0.0/16")] <- fails on Max. www.yahoo.co.uk resolves to a different ip address.
|
||||
// [InlineData(true, false, "192.168.0.0/16,www.yahoo.co.uk", "212.82.100.150,192.168.0.0/16")]
|
||||
[InlineData(true, true, "192.168.t,127.0.0.1,1234.1232.12.1234", "::ffff:127.0.0.1")]
|
||||
[InlineData(true, false, "192.168.x,127.0.0.1,1234.1232.12.1234", "127.0.0.1")]
|
||||
[InlineData(true, true, "::1", "::1/128")]
|
||||
public void TestNetworks(bool ip4, bool ip6, string hostList, string match)
|
||||
{
|
||||
using var nm = CreateNetworkManager();
|
||||
|
||||
var settings = new NetworkConfiguration
|
||||
{
|
||||
EnableIPV4 = ip4,
|
||||
EnableIPV6 = ip6
|
||||
};
|
||||
|
||||
var result = match + ',';
|
||||
ForwardedHeadersOptions options = new ForwardedHeadersOptions();
|
||||
|
||||
// Need this here as ::1 and 127.0.0.1 are in them by default.
|
||||
options.KnownProxies.Clear();
|
||||
options.KnownNetworks.Clear();
|
||||
|
||||
ApiServiceCollectionExtensions.AddProxyAddresses(settings, hostList.Split(","), options);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
foreach (var item in options.KnownProxies)
|
||||
{
|
||||
sb.Append(item);
|
||||
sb.Append(',');
|
||||
}
|
||||
|
||||
foreach (var item in options.KnownNetworks)
|
||||
{
|
||||
sb.Append(item.Prefix);
|
||||
sb.Append('/');
|
||||
sb.Append(item.PrefixLength.ToString(CultureInfo.InvariantCulture));
|
||||
sb.Append(',');
|
||||
}
|
||||
|
||||
Assert.Equal(sb.ToString(), result);
|
||||
}
|
||||
|
||||
private static IConfigurationManager GetMockConfig(NetworkConfiguration conf)
|
||||
{
|
||||
var configManager = new Mock<IConfigurationManager>
|
||||
{
|
||||
CallBase = true
|
||||
};
|
||||
configManager.Setup(x => x.GetConfiguration(It.IsAny<string>())).Returns(conf);
|
||||
return configManager.Object;
|
||||
}
|
||||
|
||||
private static NetworkManager CreateNetworkManager()
|
||||
{
|
||||
var conf = new NetworkConfiguration()
|
||||
{
|
||||
EnableIPV6 = true,
|
||||
EnableIPV4 = true,
|
||||
};
|
||||
|
||||
return new NetworkManager(GetMockConfig(conf), new NullLogger<NetworkManager>());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,13 +54,13 @@ namespace Jellyfin.Networking.Tests
|
||||
/// <summary>
|
||||
/// Checks the ability to ignore interfaces
|
||||
/// </summary>
|
||||
/// <param name="interfaces">Mock network setup, in the format (IP address, interface index, interface name) : .... </param>
|
||||
/// <param name="interfaces">Mock network setup, in the format (IP address, interface index, interface name) | .... </param>
|
||||
/// <param name="lan">LAN addresses.</param>
|
||||
/// <param name="value">Bind addresses that are excluded.</param>
|
||||
[Theory]
|
||||
[InlineData("192.168.1.208/24,-16,eth16:200.200.200.200/24,11,eth11", "192.168.1.0/24;200.200.200.0/24", "[192.168.1.208/24,200.200.200.200/24]")]
|
||||
[InlineData("192.168.1.208/24,-16,eth16:200.200.200.200/24,11,eth11", "192.168.1.0/24", "[192.168.1.208/24]")]
|
||||
[InlineData("192.168.1.208/24,-16,vEthernet1:192.168.1.208/24,-16,vEthernet212;200.200.200.200/24,11,eth11", "192.168.1.0/24", "[192.168.1.208/24]")]
|
||||
[InlineData("192.168.1.208/24,-16,eth16|200.200.200.200/24,11,eth11", "192.168.1.0/24;200.200.200.0/24", "[192.168.1.208/24,200.200.200.200/24]")]
|
||||
[InlineData("192.168.1.208/24,-16,eth16|200.200.200.200/24,11,eth11", "192.168.1.0/24", "[192.168.1.208/24]")]
|
||||
[InlineData("192.168.1.208/24,-16,vEthernet1|192.168.1.208/24,-16,vEthernet212|200.200.200.200/24,11,eth11", "192.168.1.0/24", "[192.168.1.208/24]")]
|
||||
public void IgnoreVirtualInterfaces(string interfaces, string lan, string value)
|
||||
{
|
||||
var conf = new NetworkConfiguration()
|
||||
@@ -434,7 +434,7 @@ namespace Jellyfin.Networking.Tests
|
||||
EnableIPV4 = true
|
||||
};
|
||||
|
||||
NetworkManager.MockNetworkSettings = "192.168.1.208/24,-16,eth16:200.200.200.200/24,11,eth11";
|
||||
NetworkManager.MockNetworkSettings = "192.168.1.208/24,-16,eth16|200.200.200.200/24,11,eth11";
|
||||
using var nm = new NetworkManager(GetMockConfig(conf), new NullLogger<NetworkManager>());
|
||||
NetworkManager.MockNetworkSettings = string.Empty;
|
||||
|
||||
@@ -501,7 +501,7 @@ namespace Jellyfin.Networking.Tests
|
||||
PublishedServerUriBySubnet = new string[] { publishedServers }
|
||||
};
|
||||
|
||||
NetworkManager.MockNetworkSettings = "192.168.1.208/24,-16,eth16:200.200.200.200/24,11,eth11";
|
||||
NetworkManager.MockNetworkSettings = "192.168.1.208/24,-16,eth16|200.200.200.200/24,11,eth11";
|
||||
using var nm = new NetworkManager(GetMockConfig(conf), new NullLogger<NetworkManager>());
|
||||
NetworkManager.MockNetworkSettings = string.Empty;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user