mirror of https://github.com/jellyfin/jellyfin.git
Merge branch 'master' into network-rewrite
This commit is contained in:
commit
7b90fcd053
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Setup .NET Core
|
- name: Setup .NET Core
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: '6.0.x'
|
dotnet-version: '6.0.x'
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ jobs:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||||
- name: Setup .NET Core
|
- name: Setup .NET Core
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: '6.0.x'
|
dotnet-version: '6.0.x'
|
||||||
- name: Generate openapi.json
|
- name: Generate openapi.json
|
||||||
|
@ -41,7 +41,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.base_ref }}
|
ref: ${{ github.base_ref }}
|
||||||
- name: Setup .NET Core
|
- name: Setup .NET Core
|
||||||
uses: actions/setup-dotnet@v2
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: '6.0.x'
|
dotnet-version: '6.0.x'
|
||||||
- name: Generate openapi.json
|
- name: Generate openapi.json
|
||||||
|
|
|
@ -10,7 +10,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ contains(github.repository, 'jellyfin/') }}
|
if: ${{ contains(github.repository, 'jellyfin/') }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v5
|
- uses: actions/stale@v6
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
repo-token: ${{ secrets.JF_BOT_TOKEN }}
|
||||||
days-before-stale: 120
|
days-before-stale: 120
|
||||||
|
|
|
@ -103,10 +103,7 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<ControlResponse> ProcessControlRequestAsync(ControlRequest request)
|
public Task<ControlResponse> ProcessControlRequestAsync(ControlRequest request)
|
||||||
{
|
{
|
||||||
if (request == null)
|
ArgumentNullException.ThrowIfNull(request);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(request));
|
|
||||||
}
|
|
||||||
|
|
||||||
var profile = _dlna.GetProfile(request.Headers) ?? _dlna.GetDefaultProfile();
|
var profile = _dlna.GetProfile(request.Headers) ?? _dlna.GetDefaultProfile();
|
||||||
|
|
||||||
|
|
|
@ -114,15 +114,9 @@ namespace Emby.Dlna.ContentDirectory
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override void WriteResult(string methodName, IReadOnlyDictionary<string, string> methodParams, XmlWriter xmlWriter)
|
protected override void WriteResult(string methodName, IReadOnlyDictionary<string, string> methodParams, XmlWriter xmlWriter)
|
||||||
{
|
{
|
||||||
if (xmlWriter == null)
|
ArgumentNullException.ThrowIfNull(xmlWriter);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(xmlWriter));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (methodParams == null)
|
ArgumentNullException.ThrowIfNull(methodParams);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(methodParams));
|
|
||||||
}
|
|
||||||
|
|
||||||
const string DeviceId = "test";
|
const string DeviceId = "test";
|
||||||
|
|
||||||
|
|
|
@ -100,10 +100,7 @@ namespace Emby.Dlna
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DeviceProfile? GetProfile(DeviceIdentification deviceInfo)
|
public DeviceProfile? GetProfile(DeviceIdentification deviceInfo)
|
||||||
{
|
{
|
||||||
if (deviceInfo == null)
|
ArgumentNullException.ThrowIfNull(deviceInfo);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(deviceInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
var profile = GetProfiles()
|
var profile = GetProfiles()
|
||||||
.FirstOrDefault(i => i.Identification != null && IsMatch(deviceInfo, i.Identification));
|
.FirstOrDefault(i => i.Identification != null && IsMatch(deviceInfo, i.Identification));
|
||||||
|
@ -170,10 +167,7 @@ namespace Emby.Dlna
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DeviceProfile? GetProfile(IHeaderDictionary headers)
|
public DeviceProfile? GetProfile(IHeaderDictionary headers)
|
||||||
{
|
{
|
||||||
if (headers == null)
|
ArgumentNullException.ThrowIfNull(headers);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(headers));
|
|
||||||
}
|
|
||||||
|
|
||||||
var profile = GetProfiles().FirstOrDefault(i => i.Identification != null && IsMatch(headers, i.Identification));
|
var profile = GetProfiles().FirstOrDefault(i => i.Identification != null && IsMatch(headers, i.Identification));
|
||||||
if (profile == null)
|
if (profile == null)
|
||||||
|
|
|
@ -931,10 +931,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
private static UBaseObject CreateUBaseObject(XElement container, string trackUri)
|
private static UBaseObject CreateUBaseObject(XElement container, string trackUri)
|
||||||
{
|
{
|
||||||
if (container == null)
|
ArgumentNullException.ThrowIfNull(container);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = container.GetValue(UPnpNamespaces.Res);
|
var url = container.GetValue(UPnpNamespaces.Res);
|
||||||
|
|
||||||
|
@ -958,10 +955,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
private static string[] GetProtocolInfo(XElement container)
|
private static string[] GetProtocolInfo(XElement container)
|
||||||
{
|
{
|
||||||
if (container == null)
|
ArgumentNullException.ThrowIfNull(container);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
var resElement = container.Element(UPnpNamespaces.Res);
|
var resElement = container.Element(UPnpNamespaces.Res);
|
||||||
|
|
||||||
|
@ -1183,10 +1177,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
#nullable enable
|
#nullable enable
|
||||||
private static DeviceIcon CreateIcon(XElement element)
|
private static DeviceIcon CreateIcon(XElement element)
|
||||||
{
|
{
|
||||||
if (element == null)
|
ArgumentNullException.ThrowIfNull(element);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(element));
|
|
||||||
}
|
|
||||||
|
|
||||||
var width = element.GetDescendantValue(UPnpNamespaces.Ud.GetName("width"));
|
var width = element.GetDescendantValue(UPnpNamespaces.Ud.GetName("width"));
|
||||||
var height = element.GetDescendantValue(UPnpNamespaces.Ud.GetName("height"));
|
var height = element.GetDescendantValue(UPnpNamespaces.Ud.GetName("height"));
|
||||||
|
|
|
@ -61,10 +61,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
private static Argument ArgumentFromXml(XElement container)
|
private static Argument ArgumentFromXml(XElement container)
|
||||||
{
|
{
|
||||||
if (container == null)
|
ArgumentNullException.ThrowIfNull(container);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Argument
|
return new Argument
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,10 +10,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
{
|
{
|
||||||
public static UBaseObject Create(XElement container)
|
public static UBaseObject Create(XElement container)
|
||||||
{
|
{
|
||||||
if (container == null)
|
ArgumentNullException.ThrowIfNull(container);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(container));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UBaseObject
|
return new UBaseObject
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,10 +54,7 @@ namespace Emby.Dlna.PlayTo
|
||||||
|
|
||||||
public bool Equals(UBaseObject obj)
|
public bool Equals(UBaseObject obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
ArgumentNullException.ThrowIfNull(obj);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Equals(Id, obj.Id, StringComparison.Ordinal);
|
return string.Equals(Id, obj.Id, StringComparison.Ordinal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,10 +210,7 @@ namespace Emby.Server.Implementations.AppBase
|
||||||
/// <exception cref="ArgumentNullException"><c>newConfiguration</c> is <c>null</c>.</exception>
|
/// <exception cref="ArgumentNullException"><c>newConfiguration</c> is <c>null</c>.</exception>
|
||||||
public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
|
public virtual void ReplaceConfiguration(BaseApplicationConfiguration newConfiguration)
|
||||||
{
|
{
|
||||||
if (newConfiguration == null)
|
ArgumentNullException.ThrowIfNull(newConfiguration);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(newConfiguration));
|
|
||||||
}
|
|
||||||
|
|
||||||
ValidateCachePath(newConfiguration);
|
ValidateCachePath(newConfiguration);
|
||||||
|
|
||||||
|
|
|
@ -630,8 +630,6 @@ namespace Emby.Server.Implementations
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>();
|
serviceCollection.AddSingleton<IEncodingManager, MediaEncoder.EncodingManager>();
|
||||||
|
|
||||||
serviceCollection.AddScoped<ISessionContext, SessionContext>();
|
|
||||||
|
|
||||||
serviceCollection.AddSingleton<IAuthService, AuthService>();
|
serviceCollection.AddSingleton<IAuthService, AuthService>();
|
||||||
serviceCollection.AddSingleton<IQuickConnect, QuickConnectManager>();
|
serviceCollection.AddSingleton<IQuickConnect, QuickConnectManager>();
|
||||||
|
|
||||||
|
|
|
@ -1188,10 +1188,7 @@ namespace Emby.Server.Implementations.Channels
|
||||||
|
|
||||||
internal IChannel GetChannelProvider(Channel channel)
|
internal IChannel GetChannelProvider(Channel channel)
|
||||||
{
|
{
|
||||||
if (channel == null)
|
ArgumentNullException.ThrowIfNull(channel);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(channel));
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = GetAllChannels()
|
var result = GetAllChannels()
|
||||||
.FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(channel.ChannelId) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase));
|
.FirstOrDefault(i => GetInternalChannelId(i.Name).Equals(channel.ChannelId) || string.Equals(i.Name, channel.Name, StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
|
@ -54,10 +54,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries)
|
public static void RunQueries(this SQLiteDatabaseConnection connection, string[] queries)
|
||||||
{
|
{
|
||||||
if (queries == null)
|
ArgumentNullException.ThrowIfNull(queries);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(queries));
|
|
||||||
}
|
|
||||||
|
|
||||||
connection.RunInTransaction(conn =>
|
connection.RunInTransaction(conn =>
|
||||||
{
|
{
|
||||||
|
|
|
@ -583,10 +583,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
public void SaveImages(BaseItem item)
|
public void SaveImages(BaseItem item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -617,10 +614,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void SaveItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
|
public void SaveItems(IEnumerable<BaseItem> items, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (items == null)
|
ArgumentNullException.ThrowIfNull(items);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(items));
|
|
||||||
}
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -2085,10 +2079,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
throw new ArgumentNullException(nameof(id));
|
throw new ArgumentNullException(nameof(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chapters == null)
|
ArgumentNullException.ThrowIfNull(chapters);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(chapters));
|
|
||||||
}
|
|
||||||
|
|
||||||
var idBlob = id.ToByteArray();
|
var idBlob = id.ToByteArray();
|
||||||
|
|
||||||
|
@ -2557,10 +2548,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
public int GetCount(InternalItemsQuery query)
|
public int GetCount(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -2613,10 +2601,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
public List<BaseItem> GetItemList(InternalItemsQuery query)
|
public List<BaseItem> GetItemList(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -2794,10 +2779,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
public QueryResult<BaseItem> GetItems(InternalItemsQuery query)
|
public QueryResult<BaseItem> GetItems(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -3174,10 +3156,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
public List<Guid> GetItemIdsList(InternalItemsQuery query)
|
public List<Guid> GetItemIdsList(InternalItemsQuery query)
|
||||||
{
|
{
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -4837,10 +4816,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
||||||
|
|
||||||
public List<string> GetPeopleNames(InternalPeopleQuery query)
|
public List<string> GetPeopleNames(InternalPeopleQuery query)
|
||||||
{
|
{
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -4880,10 +4856,7 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
|
||||||
|
|
||||||
public List<PersonInfo> GetPeople(InternalPeopleQuery query)
|
public List<PersonInfo> GetPeople(InternalPeopleQuery query)
|
||||||
{
|
{
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -4999,10 +4972,7 @@ AND Type = @InternalPersonType)");
|
||||||
throw new ArgumentNullException(nameof(itemId));
|
throw new ArgumentNullException(nameof(itemId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ancestorIds == null)
|
ArgumentNullException.ThrowIfNull(ancestorIds);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(ancestorIds));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -5175,10 +5145,7 @@ AND Type = @InternalPersonType)");
|
||||||
|
|
||||||
private QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType)
|
private QueryResult<(BaseItem Item, ItemCounts ItemCounts)> GetItemValues(InternalItemsQuery query, int[] itemValueTypes, string returnType)
|
||||||
{
|
{
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!query.Limit.HasValue)
|
if (!query.Limit.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -5531,10 +5498,7 @@ AND Type = @InternalPersonType)");
|
||||||
throw new ArgumentNullException(nameof(itemId));
|
throw new ArgumentNullException(nameof(itemId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values == null)
|
ArgumentNullException.ThrowIfNull(values);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(values));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -5607,10 +5571,7 @@ AND Type = @InternalPersonType)");
|
||||||
throw new ArgumentNullException(nameof(itemId));
|
throw new ArgumentNullException(nameof(itemId));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (people == null)
|
ArgumentNullException.ThrowIfNull(people);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(people));
|
|
||||||
}
|
|
||||||
|
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
|
@ -5710,10 +5671,7 @@ AND Type = @InternalPersonType)");
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
var cmdText = _mediaStreamSaveColumnsSelectQuery;
|
var cmdText = _mediaStreamSaveColumnsSelectQuery;
|
||||||
|
|
||||||
|
@ -5766,10 +5724,7 @@ AND Type = @InternalPersonType)");
|
||||||
throw new ArgumentNullException(nameof(id));
|
throw new ArgumentNullException(nameof(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (streams == null)
|
ArgumentNullException.ThrowIfNull(streams);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(streams));
|
|
||||||
}
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -6107,10 +6062,7 @@ AND Type = @InternalPersonType)");
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
if (query == null)
|
ArgumentNullException.ThrowIfNull(query);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(query));
|
|
||||||
}
|
|
||||||
|
|
||||||
var cmdText = _mediaAttachmentSaveColumnsSelectQuery;
|
var cmdText = _mediaAttachmentSaveColumnsSelectQuery;
|
||||||
|
|
||||||
|
@ -6152,10 +6104,7 @@ AND Type = @InternalPersonType)");
|
||||||
throw new ArgumentException("Guid can't be empty.", nameof(id));
|
throw new ArgumentException("Guid can't be empty.", nameof(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attachments == null)
|
ArgumentNullException.ThrowIfNull(attachments);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(attachments));
|
|
||||||
}
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
|
|
@ -133,10 +133,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SaveUserData(long userId, string key, UserItemData userData, CancellationToken cancellationToken)
|
public void SaveUserData(long userId, string key, UserItemData userData, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (userData == null)
|
ArgumentNullException.ThrowIfNull(userData);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(userData));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userId <= 0)
|
if (userId <= 0)
|
||||||
{
|
{
|
||||||
|
@ -154,10 +151,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void SaveAllUserData(long userId, UserItemData[] userData, CancellationToken cancellationToken)
|
public void SaveAllUserData(long userId, UserItemData[] userData, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (userData == null)
|
ArgumentNullException.ThrowIfNull(userData);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(userData));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userId <= 0)
|
if (userId <= 0)
|
||||||
{
|
{
|
||||||
|
@ -304,10 +298,7 @@ namespace Emby.Server.Implementations.Data
|
||||||
|
|
||||||
public UserItemData GetUserData(long userId, List<string> keys)
|
public UserItemData GetUserData(long userId, List<string> keys)
|
||||||
{
|
{
|
||||||
if (keys == null)
|
ArgumentNullException.ThrowIfNull(keys);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(keys));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keys.Count == 0)
|
if (keys.Count == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
#pragma warning disable CS1591
|
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Jellyfin.Data.Entities;
|
|
||||||
using MediaBrowser.Common.Extensions;
|
|
||||||
using MediaBrowser.Controller.Library;
|
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Session;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.HttpServer.Security
|
|
||||||
{
|
|
||||||
public class SessionContext : ISessionContext
|
|
||||||
{
|
|
||||||
private readonly IUserManager _userManager;
|
|
||||||
private readonly ISessionManager _sessionManager;
|
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
|
|
||||||
public SessionContext(IUserManager userManager, IAuthorizationContext authContext, ISessionManager sessionManager)
|
|
||||||
{
|
|
||||||
_userManager = userManager;
|
|
||||||
_authContext = authContext;
|
|
||||||
_sessionManager = sessionManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<SessionInfo> GetSession(HttpContext requestContext)
|
|
||||||
{
|
|
||||||
var authorization = await _authContext.GetAuthorizationInfo(requestContext).ConfigureAwait(false);
|
|
||||||
|
|
||||||
var user = authorization.User;
|
|
||||||
return await _sessionManager.LogSessionActivity(
|
|
||||||
authorization.Client,
|
|
||||||
authorization.Version,
|
|
||||||
authorization.DeviceId,
|
|
||||||
authorization.Device,
|
|
||||||
requestContext.GetNormalizedRemoteIp().ToString(),
|
|
||||||
user).ConfigureAwait(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<SessionInfo> GetSession(object requestContext)
|
|
||||||
{
|
|
||||||
return GetSession((HttpContext)requestContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<User?> GetUser(HttpContext requestContext)
|
|
||||||
{
|
|
||||||
var session = await GetSession(requestContext).ConfigureAwait(false);
|
|
||||||
|
|
||||||
return session.UserId.Equals(default)
|
|
||||||
? null
|
|
||||||
: _userManager.GetUserById(session.UserId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<User?> GetUser(object requestContext)
|
|
||||||
{
|
|
||||||
return GetUser(((HttpRequest)requestContext).HttpContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -93,6 +93,7 @@ namespace Emby.Server.Implementations.Images
|
||||||
returnItems.Shuffle();
|
returnItems.Shuffle();
|
||||||
return returnItems;
|
return returnItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
returnItems = items
|
returnItems = items
|
||||||
.Where(i => i.HasImage(ImageType.Primary))
|
.Where(i => i.HasImage(ImageType.Primary))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
|
@ -281,10 +281,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public void RegisterItem(BaseItem item)
|
public void RegisterItem(BaseItem item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item is IItemByName)
|
if (item is IItemByName)
|
||||||
{
|
{
|
||||||
|
@ -311,10 +308,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public void DeleteItem(BaseItem item, DeleteOptions options, bool notifyParentItem)
|
public void DeleteItem(BaseItem item, DeleteOptions options, bool notifyParentItem)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
var parent = item.GetOwner() ?? item.GetParent();
|
var parent = item.GetOwner() ?? item.GetParent();
|
||||||
|
|
||||||
|
@ -323,10 +317,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public void DeleteItem(BaseItem item, DeleteOptions options, BaseItem parent, bool notifyParentItem)
|
public void DeleteItem(BaseItem item, DeleteOptions options, BaseItem parent, bool notifyParentItem)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.SourceType == SourceType.Channel)
|
if (item.SourceType == SourceType.Channel)
|
||||||
{
|
{
|
||||||
|
@ -509,10 +500,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
throw new ArgumentNullException(nameof(key));
|
throw new ArgumentNullException(nameof(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == null)
|
ArgumentNullException.ThrowIfNull(type);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(type));
|
|
||||||
}
|
|
||||||
|
|
||||||
string programDataPath = _configurationManager.ApplicationPaths.ProgramDataPath;
|
string programDataPath = _configurationManager.ApplicationPaths.ProgramDataPath;
|
||||||
if (key.StartsWith(programDataPath, StringComparison.Ordinal))
|
if (key.StartsWith(programDataPath, StringComparison.Ordinal))
|
||||||
|
@ -544,10 +532,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
string collectionType = null,
|
string collectionType = null,
|
||||||
LibraryOptions libraryOptions = null)
|
LibraryOptions libraryOptions = null)
|
||||||
{
|
{
|
||||||
if (fileInfo == null)
|
ArgumentNullException.ThrowIfNull(fileInfo);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(fileInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
var fullPath = fileInfo.FullName;
|
var fullPath = fileInfo.FullName;
|
||||||
|
|
||||||
|
@ -1854,10 +1839,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false)
|
public async Task UpdateImagesAsync(BaseItem item, bool forceUpdate = false)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
var outdated = forceUpdate
|
var outdated = forceUpdate
|
||||||
? item.ImageInfos.Where(i => i.Path != null).ToArray()
|
? item.ImageInfos.Where(i => i.Path != null).ToArray()
|
||||||
|
@ -2296,10 +2278,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
string viewType,
|
string viewType,
|
||||||
string sortName)
|
string sortName)
|
||||||
{
|
{
|
||||||
if (parent == null)
|
ArgumentNullException.ThrowIfNull(parent);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(parent));
|
|
||||||
}
|
|
||||||
|
|
||||||
var name = parent.Name;
|
var name = parent.Name;
|
||||||
var parentId = parent.Id;
|
var parentId = parent.Id;
|
||||||
|
@ -2983,10 +2962,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
private void AddMediaPathInternal(string virtualFolderName, MediaPathInfo pathInfo, bool saveLibraryOptions)
|
private void AddMediaPathInternal(string virtualFolderName, MediaPathInfo pathInfo, bool saveLibraryOptions)
|
||||||
{
|
{
|
||||||
if (pathInfo == null)
|
ArgumentNullException.ThrowIfNull(pathInfo);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(pathInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
var path = pathInfo.Path;
|
var path = pathInfo.Path;
|
||||||
|
|
||||||
|
@ -3033,10 +3009,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public void UpdateMediaPath(string virtualFolderName, MediaPathInfo mediaPath)
|
public void UpdateMediaPath(string virtualFolderName, MediaPathInfo mediaPath)
|
||||||
{
|
{
|
||||||
if (mediaPath == null)
|
ArgumentNullException.ThrowIfNull(mediaPath);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(mediaPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
var rootFolderPath = _configurationManager.ApplicationPaths.DefaultUserViewsPath;
|
||||||
var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
|
var virtualFolderPath = Path.Combine(rootFolderPath, virtualFolderName);
|
||||||
|
|
|
@ -322,10 +322,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public List<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null)
|
public List<MediaSourceInfo> GetStaticMediaSources(BaseItem item, bool enablePathSubstitution, User user = null)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
var hasMediaSources = (IHasMediaSources)item;
|
var hasMediaSources = (IHasMediaSources)item;
|
||||||
|
|
||||||
|
|
|
@ -91,10 +91,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
|
||||||
|
|
||||||
internal static bool IsImageFile(string path, IImageProcessor imageProcessor)
|
internal static bool IsImageFile(string path, IImageProcessor imageProcessor)
|
||||||
{
|
{
|
||||||
if (path == null)
|
ArgumentNullException.ThrowIfNull(path);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
var filename = Path.GetFileNameWithoutExtension(path);
|
var filename = Path.GetFileNameWithoutExtension(path);
|
||||||
|
|
||||||
|
|
|
@ -53,15 +53,9 @@ namespace Emby.Server.Implementations.Library
|
||||||
|
|
||||||
public void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
|
public void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (userData == null)
|
ArgumentNullException.ThrowIfNull(userData);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(userData));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -194,10 +188,7 @@ namespace Emby.Server.Implementations.Library
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="data"/> is <c>null</c>.</exception>
|
||||||
private UserItemDataDto GetUserItemDataDto(UserItemData data)
|
private UserItemDataDto GetUserItemDataDto(UserItemData data)
|
||||||
{
|
{
|
||||||
if (data == null)
|
ArgumentNullException.ThrowIfNull(data);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UserItemDataDto
|
return new UserItemDataDto
|
||||||
{
|
{
|
||||||
|
|
|
@ -1223,10 +1223,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, ActiveRecordingInfo activeRecordingInfo)
|
private async Task RecordStream(TimerInfo timer, DateTime recordingEndDate, ActiveRecordingInfo activeRecordingInfo)
|
||||||
{
|
{
|
||||||
if (timer == null)
|
ArgumentNullException.ThrowIfNull(timer);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(timer));
|
|
||||||
}
|
|
||||||
|
|
||||||
LiveTvProgram programInfo = null;
|
LiveTvProgram programInfo = null;
|
||||||
|
|
||||||
|
@ -2347,10 +2344,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
private IEnumerable<TimerInfo> GetTimersForSeries(SeriesTimerInfo seriesTimer)
|
private IEnumerable<TimerInfo> GetTimersForSeries(SeriesTimerInfo seriesTimer)
|
||||||
{
|
{
|
||||||
if (seriesTimer == null)
|
ArgumentNullException.ThrowIfNull(seriesTimer);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(seriesTimer));
|
|
||||||
}
|
|
||||||
|
|
||||||
var query = new InternalItemsQuery
|
var query = new InternalItemsQuery
|
||||||
{
|
{
|
||||||
|
|
|
@ -84,10 +84,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
public virtual void Update(T item)
|
public virtual void Update(T item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_fileDataLock)
|
lock (_fileDataLock)
|
||||||
{
|
{
|
||||||
|
@ -107,10 +104,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
|
|
||||||
public virtual void Add(T item)
|
public virtual void Add(T item)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_fileDataLock)
|
lock (_fileDataLock)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using MediaBrowser.Controller.LiveTv;
|
||||||
|
|
||||||
namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
namespace Emby.Server.Implementations.LiveTv.EmbyTV
|
||||||
{
|
{
|
||||||
|
|
|
@ -44,10 +44,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
|
||||||
|
|
||||||
public async Task<Stream> GetListingsStream(TunerHostInfo info, CancellationToken cancellationToken)
|
public async Task<Stream> GetListingsStream(TunerHostInfo info, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!info.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
if (!info.Url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
"AppDeviceValues": "앱: {0}, 장치: {1}",
|
"AppDeviceValues": "앱: {0}, 장치: {1}",
|
||||||
"Application": "애플리케이션",
|
"Application": "애플리케이션",
|
||||||
"Artists": "아티스트",
|
"Artists": "아티스트",
|
||||||
"AuthenticationSucceededWithUserName": "{0}이 성공적으로 인증됨",
|
"AuthenticationSucceededWithUserName": "{0}이(가) 성공적으로 인증됨",
|
||||||
"Books": "도서",
|
"Books": "도서",
|
||||||
"CameraImageUploadedFrom": "{0}에서 새로운 카메라 이미지가 업로드됨",
|
"CameraImageUploadedFrom": "{0}에서 새로운 카메라 이미지가 업로드됨",
|
||||||
"Channels": "채널",
|
"Channels": "채널",
|
||||||
"ChapterNameValue": "챕터 {0}",
|
"ChapterNameValue": "챕터 {0}",
|
||||||
"Collections": "컬렉션",
|
"Collections": "컬렉션",
|
||||||
"DeviceOfflineWithName": "{0}의 연결 끊김",
|
"DeviceOfflineWithName": "{0}의 연결 끊김",
|
||||||
"DeviceOnlineWithName": "{0}이 연결됨",
|
"DeviceOnlineWithName": "{0}이(가) 연결됨",
|
||||||
"FailedLoginAttemptWithUserName": "{0}에서 로그인 실패",
|
"FailedLoginAttemptWithUserName": "{0}에서 로그인 실패",
|
||||||
"Favorites": "즐겨찾기",
|
"Favorites": "즐겨찾기",
|
||||||
"Folders": "폴더",
|
"Folders": "폴더",
|
||||||
|
|
|
@ -14,5 +14,111 @@
|
||||||
"HeaderLiveTV": "تور تېلېۋىزىيەسى",
|
"HeaderLiveTV": "تور تېلېۋىزىيەسى",
|
||||||
"Default": "سۈكۈتتىكى",
|
"Default": "سۈكۈتتىكى",
|
||||||
"Folders": "ھۆججەت خالتىسى",
|
"Folders": "ھۆججەت خالتىسى",
|
||||||
"Favorites": "ساقلىغۇچ"
|
"Favorites": "ساقلىغۇچ",
|
||||||
|
"LabelRunningTimeValue": "ئىجرا بولغان ۋاقتى:{0}",
|
||||||
|
"HeaderRecordingGroups": "خاتىرلەش گۇرۇپىسى",
|
||||||
|
"Forced": "ئەڭ",
|
||||||
|
"TaskKeyframeExtractor": "ھالقىلىق رامكا ئاجراتقۇچ",
|
||||||
|
"TaskKeyframeExtractorDescription": "سىن ھۆججەتلىرىدىن رامكا ئاجرىتىپ، تېخىمۇ ئېنىق بولغان HLS قويۇلۇش تىزىملىكىنى قۇرۇلىدۇ. بۇ ۋەزىپە ئۇزۇن داۋام قىلىشى مۇمكىن.",
|
||||||
|
"TaskOptimizeDatabase": "سانداننى ئەلالاشتۇرۇش",
|
||||||
|
"TaskDownloadMissingSubtitlesDescription": "ئامىللار تەڭشىكىگە ئاساسەن توردىن كەم بولغان فىلىم خېتىنى ئىزدەش.",
|
||||||
|
"TaskDownloadMissingSubtitles": "كەم بولغان فىلىم خەتلىرىنى چۈشۈرۈش",
|
||||||
|
"TasksChannelsCategory": "ئىنتېرنېت قاناللىرى",
|
||||||
|
"TaskRefreshChannelsDescription": "ئىنتېرنېت قانىلى ئۇچۇرىنى يېڭىلاش.",
|
||||||
|
"TaskRefreshChannels": "قانالنى يېڭىلاش",
|
||||||
|
"TaskCleanTranscodeDescription": "بىر كۈندىن ئاشقان ئالماشتۇرۇش ھۆججەتلىرىنى ئۆچۈرۈش.",
|
||||||
|
"TaskCleanTranscode": "ئايلاندۇرۇش ھۆججەت قىسقۇچىنى تازىلاش",
|
||||||
|
"TaskUpdatePluginsDescription": "ئاپتوماتىك يېڭىلاشقا بېكىتىلگەن قىستۇرمىلارنىڭ يېڭىلانمىسىنى چۈشۈرۈش ۋە قاچىلاش.",
|
||||||
|
"TaskUpdatePlugins": "قىستۇرمىلارنى يېڭىلاش",
|
||||||
|
"TaskRefreshPeopleDescription": "مېدىيا ئامبىرىدىكى ئارتىس ۋە رېژىسسورلارنىڭ ئۇچۇرىنى يېڭىلاش.",
|
||||||
|
"TaskRefreshPeople": "ئابونتلارنى يېڭىلاش",
|
||||||
|
"TaskCleanLogsDescription": "{0} كۈندىن ئاشقان Log ھۆججىتىنى ئۆچۈرۈش.",
|
||||||
|
"TaskCleanLogs": "Log ھۆججەت قسقۇچىنى تازىلاش",
|
||||||
|
"TaskRefreshLibraryDescription": "مېدىيا ئامبىرىغا قوشۇلغان يېڭى ھۆججەتلەرنى ئىزدەش ۋە مېدىيا ئۇچۇرلىرىنى يېڭىلاش.",
|
||||||
|
"TaskRefreshLibrary": "مېدىيا ئامبىرىنى سىكاننېرلاش",
|
||||||
|
"TaskRefreshChapterImagesDescription": "ۋېدىئو بۆلەكلىرى ئۈچۈن كىچىك سۈرەت ياساش.",
|
||||||
|
"TaskRefreshChapterImages": "بۆلەكلەر رەسىملىرىنى چىقىرىۋېلىش",
|
||||||
|
"TaskCleanCacheDescription": "سىستېما ئىھتىياجى يوق بولغان ۋاقىتلىق ھۆججەتلەرنى ئۆچۈرۈش.",
|
||||||
|
"TaskCleanCache": "ۋاقىتلىق ھۆججەت قىسقۇچنى تازىلاش",
|
||||||
|
"TaskCleanActivityLogDescription": "ۋاقىت تەڭشىكىدىن بۇرۇنقى پائالىيەت خاتىرىسى خاتىرىسىنى ئۆچۈرۈش.",
|
||||||
|
"TaskCleanActivityLog": "پروگرامما خاتىرىسىنى تازىلاش",
|
||||||
|
"TasksApplicationCategory": "پروگرامما",
|
||||||
|
"TasksLibraryCategory": "مېدىيا ئامبىرى",
|
||||||
|
"TasksMaintenanceCategory": "ئاسراش",
|
||||||
|
"VersionNumber": "نەشرى {0}",
|
||||||
|
"ValueSpecialEpisodeName": "خاسلىق - {0}",
|
||||||
|
"ValueHasBeenAddedToLibrary": "{0} مېدىيا ئامبىرىڭىزغا قوشۇلدى",
|
||||||
|
"UserStoppedPlayingItemWithValues": "{0}،{1} نى {2} دە قويۇنشتىن توختىدى",
|
||||||
|
"UserStartedPlayingItemWithValues": "{0}،{1} نى {2} دە قويۇۋاتىدۇ",
|
||||||
|
"UserPolicyUpdatedWithName": "ئابونتلار سىياسىتى {0} غا يېڭىلاندى",
|
||||||
|
"UserPasswordChangedWithName": "ئابونت{0} ئۈچۈن پارول ئۆزگەرتىلدى",
|
||||||
|
"UserOfflineFromDevice": "{0} بىلەن {1} نىڭ ئالاقىسى ئۈزۈلدى",
|
||||||
|
"UserLockedOutWithName": "ئابونت {0} قۇلۇپلاندى",
|
||||||
|
"UserDownloadingItemWithValues": "{0} چۈشۈرۈۋاتىدۇ {1}",
|
||||||
|
"UserDeletedWithName": "{0} ئابونت ئۆچۈرۈلدى",
|
||||||
|
"UserCreatedWithName": "{0} ئابونت يېڭىدىن قوشۇلدى",
|
||||||
|
"User": "ئابونت",
|
||||||
|
"Undefined": "بېكىتىلمىگەن",
|
||||||
|
"TvShows": "تىياتىرلار",
|
||||||
|
"System": "سىستېما",
|
||||||
|
"Sync": "ماس قەدەمدەش",
|
||||||
|
"SubtitleDownloadFailureFromForItem": "{0} دىن {0} نىڭ فىلىم خېتىنى چۈشۈرگىلى بولمىدى",
|
||||||
|
"StartupEmbyServerIsLoading": "Jellyfin مۇلازىمىتېرى يۈكلىنىۋاتىدۇ. سەل تۇرۇپ قايتا سىناڭ.",
|
||||||
|
"Songs": "ناخشىلار",
|
||||||
|
"Shows": "پروگراممىلار",
|
||||||
|
"ServerNameNeedsToBeRestarted": "{0} قايتا قوزغىتىلىشى كېرەك",
|
||||||
|
"ScheduledTaskStartedWithName": "{0} باشلاندى",
|
||||||
|
"ScheduledTaskFailedWithName": "{0} مەغلۇپ بولدى",
|
||||||
|
"ProviderValue": "تەمىنلىگۈچى: {0}",
|
||||||
|
"PluginUpdatedWithName": "{0} يېڭىلاندى",
|
||||||
|
"PluginUninstalledWithName": "{0} ئۆچۈرۈلدى",
|
||||||
|
"PluginInstalledWithName": "{0} قاچىلاندى",
|
||||||
|
"Plugin": "قىستۇرما",
|
||||||
|
"Playlists": "قويۇش تىزىملىكى",
|
||||||
|
"Photos": "رەسىملەر",
|
||||||
|
"NotificationOptionVideoPlaybackStopped": "سىن قويۇلۇش توختىدى",
|
||||||
|
"NotificationOptionVideoPlayback": "سىن قويۇلدى",
|
||||||
|
"NotificationOptionUserLockedOut": "ئابونت قۇلۇپلاندى",
|
||||||
|
"NotificationOptionTaskFailed": "بەلگىلەنگەن ۋەزىپە مەغلۇپ بولدى",
|
||||||
|
"NotificationOptionServerRestartRequired": "مۇلازىمىتېر قايتا قوزغىتىلىشى كېرەك",
|
||||||
|
"NotificationOptionPluginUpdateInstalled": "قىستۇرما يېڭىلانمىسى قاچىلاندى",
|
||||||
|
"NotificationOptionPluginInstalled": "قىستۇرما قاچىلاندى",
|
||||||
|
"NotificationOptionPluginUninstalled": "قىستۇرما ئۆچۈرۈلدى",
|
||||||
|
"NotificationOptionPluginError": "قىستۇرما خاتالىقى",
|
||||||
|
"NotificationOptionNewLibraryContent": "يېڭى مەزمۇن قوشۇلدى",
|
||||||
|
"NotificationOptionInstallationFailed": "قاچىلاش مەغلۇب بولدى",
|
||||||
|
"NotificationOptionCameraImageUploaded": "كامىكامېرا سۈرىتى يوللاندى",
|
||||||
|
"NotificationOptionAudioPlayback": "ئاۋاز قويۇش باشلاندى",
|
||||||
|
"NotificationOptionAudioPlaybackStopped": "ئاۋاز قويۇش توختىدى",
|
||||||
|
"NotificationOptionApplicationUpdateInstalled": "ئەپ يېڭىلانمىسى ئورنىتىلدى",
|
||||||
|
"NotificationOptionApplicationUpdateAvailable": "ئەپنىڭ نەشرىنى يېڭىلىغىلى بولۇدۇ",
|
||||||
|
"NewVersionIsAvailable": "Jellyfin Server نىڭ يېڭى نۇسخىسىنى چۈشۈرگىلى بولىدۇ.",
|
||||||
|
"NameSeasonUnknown": "نامەمۇم بۆلۈم",
|
||||||
|
"NameSeasonNumber": "{0}-بۆلۈم",
|
||||||
|
"NameInstallFailed": "{0} قاچىلاش مەغلۇپ بولدى",
|
||||||
|
"MusicVideos": "سىنلىق مۇزىكا",
|
||||||
|
"Music": "مۇزىكا",
|
||||||
|
"Movies": "فىلىملەر",
|
||||||
|
"MixedContent": "ئارىلاشما مەزمۇن",
|
||||||
|
"MessageNamedServerConfigurationUpdatedWithValue": "مۇلازىمىتېر تەڭشىكىنىڭ {0} قىسمى يېڭىلىنىپ بولدى",
|
||||||
|
"MessageServerConfigurationUpdated": "مۇلازىمىتېر يېڭىلىنىپ بولدى",
|
||||||
|
"MessageApplicationUpdated": "Jellyfin مۇلازىمىتېرى يېڭىلاندى",
|
||||||
|
"MessageApplicationUpdatedTo": "Jellyfin مۇلازىمىتېر نەشرى {0} گە يېڭىلاندى",
|
||||||
|
"Latest": "ئەڭ يېڭى",
|
||||||
|
"LabelIpAddressValue": "{0}: IP ئادرىسى",
|
||||||
|
"ItemRemovedWithName": "{0} ئامباردىن چىقىرىلدى",
|
||||||
|
"ItemAddedWithName": "{0} ئامبارغا قوشۇلدى",
|
||||||
|
"Inherit": "داۋاملاشتۇرۇش",
|
||||||
|
"HomeVideos": "ئائىلە سىنلىرى",
|
||||||
|
"HeaderNextUp": "كېيىنكىسى",
|
||||||
|
"HeaderFavoriteSongs": "ئەڭ ياقتۇرىدىغان ناخشىلار",
|
||||||
|
"HeaderFavoriteShows": "ئەڭ ياقتۇرىدىغان پروگراممىلار",
|
||||||
|
"HeaderFavoriteEpisodes": "ئەڭ ياقتۇرىدىغان تىياتېرلار",
|
||||||
|
"HeaderFavoriteArtists": "ئەڭ ياقتۇرىدىغان سەنئەتكارلار",
|
||||||
|
"HeaderFavoriteAlbums": "ياقتۇرىدىغان پىلاستىنكىلار",
|
||||||
|
"HeaderContinueWatching": "داۋاملىق كۆرۈش",
|
||||||
|
"HeaderAlbumArtists": "پىلاستىنكا سەنئەتكارلىرى",
|
||||||
|
"Genres": "ئۇسلۇبلار",
|
||||||
|
"FailedLoginAttemptWithUserName": "{0} كىرىش ئوڭۇشلۇق بولمىدى",
|
||||||
|
"External": "سىرتقى"
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,7 @@ namespace Emby.Server.Implementations.Net
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public ISocket CreateUdpMulticastSocket(IPAddress ipAddress, IPAddress bindIpAddress, int multicastTimeToLive, int localPort)
|
public ISocket CreateUdpMulticastSocket(IPAddress ipAddress, IPAddress bindIpAddress, int multicastTimeToLive, int localPort)
|
||||||
{
|
{
|
||||||
if (ipAddress == null)
|
ArgumentNullException.ThrowIfNull(ipAddress);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(ipAddress));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bindIpAddress == null)
|
if (bindIpAddress == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,10 +35,7 @@ namespace Emby.Server.Implementations.Net
|
||||||
|
|
||||||
public UdpSocket(Socket socket, int localPort, IPAddress ip)
|
public UdpSocket(Socket socket, int localPort, IPAddress ip)
|
||||||
{
|
{
|
||||||
if (socket == null)
|
ArgumentNullException.ThrowIfNull(socket);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(socket));
|
|
||||||
}
|
|
||||||
|
|
||||||
_socket = socket;
|
_socket = socket;
|
||||||
_localPort = localPort;
|
_localPort = localPort;
|
||||||
|
@ -51,10 +48,7 @@ namespace Emby.Server.Implementations.Net
|
||||||
|
|
||||||
public UdpSocket(Socket socket, IPEndPoint endPoint)
|
public UdpSocket(Socket socket, IPEndPoint endPoint)
|
||||||
{
|
{
|
||||||
if (socket == null)
|
ArgumentNullException.ThrowIfNull(socket);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(socket));
|
|
||||||
}
|
|
||||||
|
|
||||||
_socket = socket;
|
_socket = socket;
|
||||||
_socket.Connect(endPoint);
|
_socket.Connect(endPoint);
|
||||||
|
|
|
@ -234,10 +234,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||||
/// <returns>Outcome of the operation.</returns>
|
/// <returns>Outcome of the operation.</returns>
|
||||||
public bool RemovePlugin(LocalPlugin plugin)
|
public bool RemovePlugin(LocalPlugin plugin)
|
||||||
{
|
{
|
||||||
if (plugin == null)
|
ArgumentNullException.ThrowIfNull(plugin);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(plugin));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DeletePlugin(plugin))
|
if (DeletePlugin(plugin))
|
||||||
{
|
{
|
||||||
|
@ -288,10 +285,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||||
/// <param name="plugin">The <see cref="LocalPlugin"/> of the plug to disable.</param>
|
/// <param name="plugin">The <see cref="LocalPlugin"/> of the plug to disable.</param>
|
||||||
public void EnablePlugin(LocalPlugin plugin)
|
public void EnablePlugin(LocalPlugin plugin)
|
||||||
{
|
{
|
||||||
if (plugin == null)
|
ArgumentNullException.ThrowIfNull(plugin);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(plugin));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ChangePluginState(plugin, PluginStatus.Active))
|
if (ChangePluginState(plugin, PluginStatus.Active))
|
||||||
{
|
{
|
||||||
|
@ -306,10 +300,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||||
/// <param name="plugin">The <see cref="LocalPlugin"/> of the plug to disable.</param>
|
/// <param name="plugin">The <see cref="LocalPlugin"/> of the plug to disable.</param>
|
||||||
public void DisablePlugin(LocalPlugin plugin)
|
public void DisablePlugin(LocalPlugin plugin)
|
||||||
{
|
{
|
||||||
if (plugin == null)
|
ArgumentNullException.ThrowIfNull(plugin);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(plugin));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the manifest on disk
|
// Update the manifest on disk
|
||||||
if (ChangePluginState(plugin, PluginStatus.Disabled))
|
if (ChangePluginState(plugin, PluginStatus.Disabled))
|
||||||
|
@ -326,10 +317,7 @@ namespace Emby.Server.Implementations.Plugins
|
||||||
public void FailPlugin(Assembly assembly)
|
public void FailPlugin(Assembly assembly)
|
||||||
{
|
{
|
||||||
// Only save if disabled.
|
// Only save if disabled.
|
||||||
if (assembly == null)
|
ArgumentNullException.ThrowIfNull(assembly);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(assembly));
|
|
||||||
}
|
|
||||||
|
|
||||||
var plugin = _plugins.FirstOrDefault(p => p.DllFiles.Contains(assembly.Location));
|
var plugin = _plugins.FirstOrDefault(p => p.DllFiles.Contains(assembly.Location));
|
||||||
if (plugin == null)
|
if (plugin == null)
|
||||||
|
|
|
@ -92,25 +92,13 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, ILogger logger)
|
public ScheduledTaskWorker(IScheduledTask scheduledTask, IApplicationPaths applicationPaths, ITaskManager taskManager, ILogger logger)
|
||||||
{
|
{
|
||||||
if (scheduledTask == null)
|
ArgumentNullException.ThrowIfNull(scheduledTask);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(scheduledTask));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (applicationPaths == null)
|
ArgumentNullException.ThrowIfNull(applicationPaths);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(applicationPaths));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (taskManager == null)
|
ArgumentNullException.ThrowIfNull(taskManager);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(taskManager));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logger == null)
|
ArgumentNullException.ThrowIfNull(logger);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(logger));
|
|
||||||
}
|
|
||||||
|
|
||||||
ScheduledTask = scheduledTask;
|
ScheduledTask = scheduledTask;
|
||||||
_applicationPaths = applicationPaths;
|
_applicationPaths = applicationPaths;
|
||||||
|
@ -249,10 +237,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
get => _triggers;
|
get => _triggers;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == null)
|
ArgumentNullException.ThrowIfNull(value);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup current triggers
|
// Cleanup current triggers
|
||||||
if (_triggers != null)
|
if (_triggers != null)
|
||||||
|
@ -281,10 +266,7 @@ namespace Emby.Server.Implementations.ScheduledTasks
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == null)
|
ArgumentNullException.ThrowIfNull(value);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
// This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly
|
// This null check is not great, but is needed to handle bad user input, or user mucking with the config file incorrectly
|
||||||
var triggerList = value.Where(i => i != null).ToArray();
|
var triggerList = value.Where(i => i != null).ToArray();
|
||||||
|
|
|
@ -665,10 +665,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
var session = GetSession(info.SessionId);
|
var session = GetSession(info.SessionId);
|
||||||
|
|
||||||
|
@ -762,10 +759,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
var session = GetSession(info.SessionId);
|
var session = GetSession(info.SessionId);
|
||||||
|
|
||||||
|
@ -897,10 +891,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
CheckDisposed();
|
CheckDisposed();
|
||||||
|
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
|
if (info.PositionTicks.HasValue && info.PositionTicks.Value < 0)
|
||||||
{
|
{
|
||||||
|
@ -1341,15 +1332,9 @@ namespace Emby.Server.Implementations.Session
|
||||||
|
|
||||||
private static void AssertCanControl(SessionInfo session, SessionInfo controllingSession)
|
private static void AssertCanControl(SessionInfo session, SessionInfo controllingSession)
|
||||||
{
|
{
|
||||||
if (session == null)
|
ArgumentNullException.ThrowIfNull(session);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(session));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (controllingSession == null)
|
ArgumentNullException.ThrowIfNull(controllingSession);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(controllingSession));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1688,10 +1673,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private BaseItemDto GetItemInfo(BaseItem item, MediaSourceInfo mediaSource)
|
private BaseItemDto GetItemInfo(BaseItem item, MediaSourceInfo mediaSource)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
var dtoOptions = _itemInfoDtoOptions;
|
var dtoOptions = _itemInfoDtoOptions;
|
||||||
|
|
||||||
|
@ -1802,10 +1784,7 @@ namespace Emby.Server.Implementations.Session
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Task<SessionInfo> GetSessionByAuthenticationToken(Device info, string deviceId, string remoteEndpoint, string appVersion)
|
public Task<SessionInfo> GetSessionByAuthenticationToken(Device info, string deviceId, string remoteEndpoint, string appVersion)
|
||||||
{
|
{
|
||||||
if (info == null)
|
ArgumentNullException.ThrowIfNull(info);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(info));
|
|
||||||
}
|
|
||||||
|
|
||||||
var user = info.UserId.Equals(default)
|
var user = info.UserId.Equals(default)
|
||||||
? null
|
? null
|
||||||
|
|
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
|
@ -53,7 +54,6 @@ namespace Emby.Server.Implementations.Session
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
private readonly ILogger<SessionWebSocketListener> _logger;
|
private readonly ILogger<SessionWebSocketListener> _logger;
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
private readonly IAuthorizationContext _authorizationContext;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The KeepAlive cancellation token.
|
/// The KeepAlive cancellation token.
|
||||||
|
@ -66,17 +66,14 @@ namespace Emby.Server.Implementations.Session
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
/// <param name="sessionManager">The session manager.</param>
|
/// <param name="sessionManager">The session manager.</param>
|
||||||
/// <param name="loggerFactory">The logger factory.</param>
|
/// <param name="loggerFactory">The logger factory.</param>
|
||||||
/// <param name="authorizationContext">The authorization context.</param>
|
|
||||||
public SessionWebSocketListener(
|
public SessionWebSocketListener(
|
||||||
ILogger<SessionWebSocketListener> logger,
|
ILogger<SessionWebSocketListener> logger,
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory)
|
||||||
IAuthorizationContext authorizationContext)
|
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
_authorizationContext = authorizationContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
@ -110,21 +107,18 @@ namespace Emby.Server.Implementations.Session
|
||||||
|
|
||||||
private async Task<SessionInfo> GetSession(HttpContext httpContext, string remoteEndpoint)
|
private async Task<SessionInfo> GetSession(HttpContext httpContext, string remoteEndpoint)
|
||||||
{
|
{
|
||||||
var authorizationInfo = await _authorizationContext.GetAuthorizationInfo(httpContext)
|
if (!httpContext.User.Identity?.IsAuthenticated ?? false)
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (!authorizationInfo.IsAuthenticated)
|
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var deviceId = authorizationInfo.DeviceId;
|
var deviceId = httpContext.User.GetDeviceId();
|
||||||
if (httpContext.Request.Query.TryGetValue("deviceId", out var queryDeviceId))
|
if (httpContext.Request.Query.TryGetValue("deviceId", out var queryDeviceId))
|
||||||
{
|
{
|
||||||
deviceId = queryDeviceId;
|
deviceId = queryDeviceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return await _sessionManager.GetSessionByAuthenticationToken(authorizationInfo.Token, deviceId, remoteEndpoint)
|
return await _sessionManager.GetSessionByAuthenticationToken(httpContext.User.GetToken(), deviceId, remoteEndpoint)
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem? x, BaseItem? y)
|
public int Compare(BaseItem? x, BaseItem? y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
var episode1 = x as Episode;
|
var episode1 = x as Episode;
|
||||||
var episode2 = y as Episode;
|
var episode2 = y as Episode;
|
||||||
|
|
|
@ -23,15 +23,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem? x, BaseItem? y)
|
public int Compare(BaseItem? x, BaseItem? y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (x.CommunityRating ?? 0).CompareTo(y.CommunityRating ?? 0);
|
return (x.CommunityRating ?? 0).CompareTo(y.CommunityRating ?? 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem? x, BaseItem? y)
|
public int Compare(BaseItem? x, BaseItem? y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
return DateTime.Compare(x.DateCreated, y.DateCreated);
|
return DateTime.Compare(x.DateCreated, y.DateCreated);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem? x, BaseItem? y)
|
public int Compare(BaseItem? x, BaseItem? y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x.IndexNumber.HasValue && !y.IndexNumber.HasValue)
|
if (!x.IndexNumber.HasValue && !y.IndexNumber.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem? x, BaseItem? y)
|
public int Compare(BaseItem? x, BaseItem? y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
|
return string.Compare(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,15 +31,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem? x, BaseItem? y)
|
public int Compare(BaseItem? x, BaseItem? y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
var levelX = string.IsNullOrEmpty(x.OfficialRating) ? 0 : _localization.GetRatingLevel(x.OfficialRating) ?? 0;
|
var levelX = string.IsNullOrEmpty(x.OfficialRating) ? 0 : _localization.GetRatingLevel(x.OfficialRating) ?? 0;
|
||||||
var levelY = string.IsNullOrEmpty(y.OfficialRating) ? 0 : _localization.GetRatingLevel(y.OfficialRating) ?? 0;
|
var levelY = string.IsNullOrEmpty(y.OfficialRating) ? 0 : _localization.GetRatingLevel(y.OfficialRating) ?? 0;
|
||||||
|
|
|
@ -24,15 +24,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem? x, BaseItem? y)
|
public int Compare(BaseItem? x, BaseItem? y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!x.ParentIndexNumber.HasValue && !y.ParentIndexNumber.HasValue)
|
if (!x.ParentIndexNumber.HasValue && !y.ParentIndexNumber.HasValue)
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,15 +26,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem x, BaseItem y)
|
public int Compare(BaseItem x, BaseItem y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (x.RunTimeTicks ?? 0).CompareTo(y.RunTimeTicks ?? 0);
|
return (x.RunTimeTicks ?? 0).CompareTo(y.RunTimeTicks ?? 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem x, BaseItem y)
|
public int Compare(BaseItem x, BaseItem y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Compare(x.SortName, y.SortName, StringComparison.OrdinalIgnoreCase);
|
return string.Compare(x.SortName, y.SortName, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,9 @@ namespace Emby.Server.Implementations.Sorting
|
||||||
/// <returns>System.Int32.</returns>
|
/// <returns>System.Int32.</returns>
|
||||||
public int Compare(BaseItem x, BaseItem y)
|
public int Compare(BaseItem x, BaseItem y)
|
||||||
{
|
{
|
||||||
if (x == null)
|
ArgumentNullException.ThrowIfNull(x);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(x));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y == null)
|
ArgumentNullException.ThrowIfNull(y);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(y));
|
|
||||||
}
|
|
||||||
|
|
||||||
return AlphanumericComparator.CompareValues(x.Studios.FirstOrDefault(), y.Studios.FirstOrDefault());
|
return AlphanumericComparator.CompareValues(x.Studios.FirstOrDefault(), y.Studios.FirstOrDefault());
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,10 +294,7 @@ namespace Emby.Server.Implementations.Updates
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task InstallPackage(InstallationInfo package, CancellationToken cancellationToken)
|
public async Task InstallPackage(InstallationInfo package, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (package == null)
|
ArgumentNullException.ThrowIfNull(package);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(package));
|
|
||||||
}
|
|
||||||
|
|
||||||
var innerCancellationTokenSource = new CancellationTokenSource();
|
var innerCancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,6 @@ namespace Jellyfin.Api.Attributes
|
||||||
/// <param name="template">The route template. May not be null.</param>
|
/// <param name="template">The route template. May not be null.</param>
|
||||||
public HttpSubscribeAttribute(string template)
|
public HttpSubscribeAttribute(string template)
|
||||||
: base(_supportedMethods, template)
|
: base(_supportedMethods, template)
|
||||||
=> ArgumentNullException.ThrowIfNull(template, nameof(template));
|
=> ArgumentNullException.ThrowIfNull(template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,6 @@ namespace Jellyfin.Api.Attributes
|
||||||
/// <param name="template">The route template. May not be null.</param>
|
/// <param name="template">The route template. May not be null.</param>
|
||||||
public HttpUnsubscribeAttribute(string template)
|
public HttpUnsubscribeAttribute(string template)
|
||||||
: base(_supportedMethods, template)
|
: base(_supportedMethods, template)
|
||||||
=> ArgumentNullException.ThrowIfNull(template, nameof(template));
|
=> ArgumentNullException.ThrowIfNull(template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
|
@ -51,21 +52,21 @@ namespace Jellyfin.Api.Auth
|
||||||
bool requiredDownloadPermission = false)
|
bool requiredDownloadPermission = false)
|
||||||
{
|
{
|
||||||
// ApiKey is currently global admin, always allow.
|
// ApiKey is currently global admin, always allow.
|
||||||
var isApiKey = ClaimHelpers.GetIsApiKey(claimsPrincipal);
|
var isApiKey = claimsPrincipal.GetIsApiKey();
|
||||||
if (isApiKey)
|
if (isApiKey)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure claim has userId.
|
// Ensure claim has userId.
|
||||||
var userId = ClaimHelpers.GetUserId(claimsPrincipal);
|
var userId = claimsPrincipal.GetUserId();
|
||||||
if (!userId.HasValue)
|
if (userId.Equals(default))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure userId links to a valid user.
|
// Ensure userId links to a valid user.
|
||||||
var user = _userManager.GetUserById(userId.Value);
|
var user = _userManager.GetUserById(userId);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
@ -44,14 +45,14 @@ namespace Jellyfin.Api.Auth.SyncPlayAccessPolicy
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
var userId = ClaimHelpers.GetUserId(context.User);
|
var userId = context.User.GetUserId();
|
||||||
var user = _userManager.GetUserById(userId!.Value);
|
var user = _userManager.GetUserById(userId);
|
||||||
|
|
||||||
if (requirement.RequiredAccess == SyncPlayAccessRequirementType.HasAccess)
|
if (requirement.RequiredAccess == SyncPlayAccessRequirementType.HasAccess)
|
||||||
{
|
{
|
||||||
if (user.SyncPlayAccess == SyncPlayUserAccessType.CreateAndJoinGroups
|
if (user.SyncPlayAccess == SyncPlayUserAccessType.CreateAndJoinGroups
|
||||||
|| user.SyncPlayAccess == SyncPlayUserAccessType.JoinGroups
|
|| user.SyncPlayAccess == SyncPlayUserAccessType.JoinGroups
|
||||||
|| _syncPlayManager.IsUserActive(userId.Value))
|
|| _syncPlayManager.IsUserActive(userId))
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
}
|
}
|
||||||
|
@ -85,7 +86,7 @@ namespace Jellyfin.Api.Auth.SyncPlayAccessPolicy
|
||||||
}
|
}
|
||||||
else if (requirement.RequiredAccess == SyncPlayAccessRequirementType.IsInGroup)
|
else if (requirement.RequiredAccess == SyncPlayAccessRequirementType.IsInGroup)
|
||||||
{
|
{
|
||||||
if (_syncPlayManager.IsUserActive(userId.Value))
|
if (_syncPlayManager.IsUserActive(userId))
|
||||||
{
|
{
|
||||||
context.Succeed(requirement);
|
context.Succeed(requirement);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = null;
|
User? user = null;
|
||||||
|
@ -323,7 +323,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = null;
|
User? user = null;
|
||||||
|
@ -463,7 +463,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public ActionResult<BaseItemDto> GetArtistByName([FromRoute, Required] string name, [FromQuery] Guid? userId)
|
public ActionResult<BaseItemDto> GetArtistByName([FromRoute, Required] string name, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
var item = _libraryManager.GetArtist(name, dtoOptions);
|
var item = _libraryManager.GetArtist(name, dtoOptions);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Attributes;
|
using Jellyfin.Api.Attributes;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.Models.ClientLogDtos;
|
using Jellyfin.Api.Models.ClientLogDtos;
|
||||||
using MediaBrowser.Controller.ClientEvent;
|
using MediaBrowser.Controller.ClientEvent;
|
||||||
|
@ -69,10 +70,10 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
private (string ClientName, string ClientVersion) GetRequestInformation()
|
private (string ClientName, string ClientVersion) GetRequestInformation()
|
||||||
{
|
{
|
||||||
var clientName = ClaimHelpers.GetClient(HttpContext.User) ?? "unknown-client";
|
var clientName = HttpContext.User.GetClient() ?? "unknown-client";
|
||||||
var clientVersion = ClaimHelpers.GetIsApiKey(HttpContext.User)
|
var clientVersion = HttpContext.User.GetIsApiKey()
|
||||||
? "apikey"
|
? "apikey"
|
||||||
: ClaimHelpers.GetVersion(HttpContext.User) ?? "unknown-version";
|
: HttpContext.User.GetVersion() ?? "unknown-version";
|
||||||
|
|
||||||
return (clientName, clientVersion);
|
return (clientName, clientVersion);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using MediaBrowser.Controller.Collections;
|
using MediaBrowser.Controller.Collections;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Collections;
|
using MediaBrowser.Model.Collections;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
@ -23,22 +22,18 @@ namespace Jellyfin.Api.Controllers
|
||||||
{
|
{
|
||||||
private readonly ICollectionManager _collectionManager;
|
private readonly ICollectionManager _collectionManager;
|
||||||
private readonly IDtoService _dtoService;
|
private readonly IDtoService _dtoService;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="CollectionController"/> class.
|
/// Initializes a new instance of the <see cref="CollectionController"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="collectionManager">Instance of <see cref="ICollectionManager"/> interface.</param>
|
/// <param name="collectionManager">Instance of <see cref="ICollectionManager"/> interface.</param>
|
||||||
/// <param name="dtoService">Instance of <see cref="IDtoService"/> interface.</param>
|
/// <param name="dtoService">Instance of <see cref="IDtoService"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
public CollectionController(
|
public CollectionController(
|
||||||
ICollectionManager collectionManager,
|
ICollectionManager collectionManager,
|
||||||
IDtoService dtoService,
|
IDtoService dtoService)
|
||||||
IAuthorizationContext authContext)
|
|
||||||
{
|
{
|
||||||
_collectionManager = collectionManager;
|
_collectionManager = collectionManager;
|
||||||
_dtoService = dtoService;
|
_dtoService = dtoService;
|
||||||
_authContext = authContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -58,7 +53,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] Guid? parentId,
|
[FromQuery] Guid? parentId,
|
||||||
[FromQuery] bool isLocked = false)
|
[FromQuery] bool isLocked = false)
|
||||||
{
|
{
|
||||||
var userId = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).UserId;
|
var userId = User.GetUserId();
|
||||||
|
|
||||||
var item = await _collectionManager.CreateCollectionAsync(new CollectionCreationOptions
|
var item = await _collectionManager.CreateCollectionAsync(new CollectionCreationOptions
|
||||||
{
|
{
|
||||||
|
@ -69,7 +64,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
UserIds = new[] { userId }
|
UserIds = new[] { userId }
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
var dto = _dtoService.GetBaseItemDto(item, dtoOptions);
|
var dto = _dtoService.GetBaseItemDto(item, dtoOptions);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.IO;
|
using MediaBrowser.Model.IO;
|
||||||
|
@ -46,7 +45,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly IDlnaManager _dlnaManager;
|
private readonly IDlnaManager _dlnaManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
private readonly IServerConfigurationManager _serverConfigurationManager;
|
private readonly IServerConfigurationManager _serverConfigurationManager;
|
||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
|
@ -65,7 +63,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
||||||
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
||||||
|
@ -80,7 +77,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IDlnaManager dlnaManager,
|
IDlnaManager dlnaManager,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IServerConfigurationManager serverConfigurationManager,
|
IServerConfigurationManager serverConfigurationManager,
|
||||||
IMediaEncoder mediaEncoder,
|
IMediaEncoder mediaEncoder,
|
||||||
|
@ -95,7 +91,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_dlnaManager = dlnaManager;
|
_dlnaManager = dlnaManager;
|
||||||
_authContext = authContext;
|
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
|
@ -287,8 +282,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
var cancellationToken = cancellationTokenSource.Token;
|
var cancellationToken = cancellationTokenSource.Token;
|
||||||
var state = await StreamingHelpers.GetStreamingState(
|
var state = await StreamingHelpers.GetStreamingState(
|
||||||
streamingRequest,
|
streamingRequest,
|
||||||
Request,
|
HttpContext,
|
||||||
_authContext,
|
|
||||||
_mediaSourceManager,
|
_mediaSourceManager,
|
||||||
_userManager,
|
_userManager,
|
||||||
_libraryManager,
|
_libraryManager,
|
||||||
|
@ -1393,8 +1387,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
{
|
{
|
||||||
using var state = await StreamingHelpers.GetStreamingState(
|
using var state = await StreamingHelpers.GetStreamingState(
|
||||||
streamingRequest,
|
streamingRequest,
|
||||||
Request,
|
HttpContext,
|
||||||
_authContext,
|
|
||||||
_mediaSourceManager,
|
_mediaSourceManager,
|
||||||
_userManager,
|
_userManager,
|
||||||
_libraryManager,
|
_libraryManager,
|
||||||
|
@ -1434,8 +1427,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
var state = await StreamingHelpers.GetStreamingState(
|
var state = await StreamingHelpers.GetStreamingState(
|
||||||
streamingRequest,
|
streamingRequest,
|
||||||
Request,
|
HttpContext,
|
||||||
_authContext,
|
|
||||||
_mediaSourceManager,
|
_mediaSourceManager,
|
||||||
_userManager,
|
_userManager,
|
||||||
_libraryManager,
|
_libraryManager,
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId is null || userId.Value.Equals(default)
|
User? user = userId is null || userId.Value.Equals(default)
|
||||||
|
@ -157,7 +157,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public ActionResult<BaseItemDto> GetGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
|
public ActionResult<BaseItemDto> GetGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions()
|
var dtoOptions = new DtoOptions()
|
||||||
.AddClientFields(Request);
|
.AddClientFields(User);
|
||||||
|
|
||||||
Genre? item;
|
Genre? item;
|
||||||
if (genreName.Contains(BaseItem.SlugChar, StringComparison.OrdinalIgnoreCase))
|
if (genreName.Contains(BaseItem.SlugChar, StringComparison.OrdinalIgnoreCase))
|
||||||
|
|
|
@ -17,7 +17,6 @@ using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Drawing;
|
using MediaBrowser.Controller.Drawing;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Branding;
|
using MediaBrowser.Model.Branding;
|
||||||
using MediaBrowser.Model.Drawing;
|
using MediaBrowser.Model.Drawing;
|
||||||
|
@ -44,11 +43,9 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly IProviderManager _providerManager;
|
private readonly IProviderManager _providerManager;
|
||||||
private readonly IImageProcessor _imageProcessor;
|
private readonly IImageProcessor _imageProcessor;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly ILogger<ImageController> _logger;
|
private readonly ILogger<ImageController> _logger;
|
||||||
private readonly IServerConfigurationManager _serverConfigurationManager;
|
private readonly IServerConfigurationManager _serverConfigurationManager;
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
private readonly IImageEncoder _imageEncoder;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ImageController"/> class.
|
/// Initializes a new instance of the <see cref="ImageController"/> class.
|
||||||
|
@ -58,33 +55,27 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
/// <param name="providerManager">Instance of the <see cref="IProviderManager"/> interface.</param>
|
||||||
/// <param name="imageProcessor">Instance of the <see cref="IImageProcessor"/> interface.</param>
|
/// <param name="imageProcessor">Instance of the <see cref="IImageProcessor"/> interface.</param>
|
||||||
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
/// <param name="fileSystem">Instance of the <see cref="IFileSystem"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger{ImageController}"/> interface.</param>
|
/// <param name="logger">Instance of the <see cref="ILogger{ImageController}"/> interface.</param>
|
||||||
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
||||||
/// <param name="appPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
|
/// <param name="appPaths">Instance of the <see cref="IApplicationPaths"/> interface.</param>
|
||||||
/// <param name="imageEncoder">Instance of the <see cref="IImageEncoder"/> interface.</param>
|
|
||||||
public ImageController(
|
public ImageController(
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IProviderManager providerManager,
|
IProviderManager providerManager,
|
||||||
IImageProcessor imageProcessor,
|
IImageProcessor imageProcessor,
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
ILogger<ImageController> logger,
|
ILogger<ImageController> logger,
|
||||||
IServerConfigurationManager serverConfigurationManager,
|
IServerConfigurationManager serverConfigurationManager,
|
||||||
IApplicationPaths appPaths,
|
IApplicationPaths appPaths)
|
||||||
IImageEncoder imageEncoder)
|
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_providerManager = providerManager;
|
_providerManager = providerManager;
|
||||||
_imageProcessor = imageProcessor;
|
_imageProcessor = imageProcessor;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_authContext = authContext;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
_appPaths = appPaths;
|
_appPaths = appPaths;
|
||||||
_imageEncoder = imageEncoder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -108,7 +99,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] ImageType imageType,
|
[FromRoute, Required] ImageType imageType,
|
||||||
[FromQuery] int? index = null)
|
[FromQuery] int? index = null)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
|
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
|
||||||
}
|
}
|
||||||
|
@ -155,7 +146,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] ImageType imageType,
|
[FromRoute, Required] ImageType imageType,
|
||||||
[FromRoute] int index)
|
[FromRoute] int index)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
|
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the image.");
|
||||||
}
|
}
|
||||||
|
@ -201,7 +192,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] ImageType imageType,
|
[FromRoute, Required] ImageType imageType,
|
||||||
[FromQuery] int? index = null)
|
[FromQuery] int? index = null)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to delete the image.");
|
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to delete the image.");
|
||||||
}
|
}
|
||||||
|
@ -245,7 +236,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] ImageType imageType,
|
[FromRoute, Required] ImageType imageType,
|
||||||
[FromRoute] int index)
|
[FromRoute] int index)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, HttpContext.User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to delete the image.");
|
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to delete the image.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
||||||
return GetResult(items, user, limit, dtoOptions);
|
return GetResult(items, user, limit, dtoOptions);
|
||||||
|
@ -115,7 +115,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
var items = _musicManager.GetInstantMixFromItem(album, user, dtoOptions);
|
var items = _musicManager.GetInstantMixFromItem(album, user, dtoOptions);
|
||||||
return GetResult(items, user, limit, dtoOptions);
|
return GetResult(items, user, limit, dtoOptions);
|
||||||
|
@ -151,7 +151,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
var items = _musicManager.GetInstantMixFromItem(playlist, user, dtoOptions);
|
var items = _musicManager.GetInstantMixFromItem(playlist, user, dtoOptions);
|
||||||
return GetResult(items, user, limit, dtoOptions);
|
return GetResult(items, user, limit, dtoOptions);
|
||||||
|
@ -186,7 +186,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
var items = _musicManager.GetInstantMixFromGenres(new[] { name }, user, dtoOptions);
|
var items = _musicManager.GetInstantMixFromGenres(new[] { name }, user, dtoOptions);
|
||||||
return GetResult(items, user, limit, dtoOptions);
|
return GetResult(items, user, limit, dtoOptions);
|
||||||
|
@ -222,7 +222,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
||||||
return GetResult(items, user, limit, dtoOptions);
|
return GetResult(items, user, limit, dtoOptions);
|
||||||
|
@ -258,7 +258,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
||||||
return GetResult(items, user, limit, dtoOptions);
|
return GetResult(items, user, limit, dtoOptions);
|
||||||
|
@ -331,7 +331,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
var items = _musicManager.GetInstantMixFromItem(item, user, dtoOptions);
|
||||||
return GetResult(items, user, limit, dtoOptions);
|
return GetResult(items, user, limit, dtoOptions);
|
||||||
|
|
|
@ -10,7 +10,6 @@ using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -34,7 +33,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILocalizationManager _localization;
|
private readonly ILocalizationManager _localization;
|
||||||
private readonly IDtoService _dtoService;
|
private readonly IDtoService _dtoService;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly ILogger<ItemsController> _logger;
|
private readonly ILogger<ItemsController> _logger;
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
|
|
||||||
|
@ -45,7 +43,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
|
/// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
|
||||||
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
|
||||||
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||||
public ItemsController(
|
public ItemsController(
|
||||||
|
@ -53,7 +50,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
ILocalizationManager localization,
|
ILocalizationManager localization,
|
||||||
IDtoService dtoService,
|
IDtoService dtoService,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
ILogger<ItemsController> logger,
|
ILogger<ItemsController> logger,
|
||||||
ISessionManager sessionManager)
|
ISessionManager sessionManager)
|
||||||
{
|
{
|
||||||
|
@ -61,7 +57,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_localization = localization;
|
_localization = localization;
|
||||||
_dtoService = dtoService;
|
_dtoService = dtoService;
|
||||||
_authContext = authContext;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +152,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items.</returns>
|
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items.</returns>
|
||||||
[HttpGet("Items")]
|
[HttpGet("Items")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<QueryResult<BaseItemDto>>> GetItems(
|
public ActionResult<QueryResult<BaseItemDto>> GetItems(
|
||||||
[FromQuery] Guid? userId,
|
[FromQuery] Guid? userId,
|
||||||
[FromQuery] string? maxOfficialRating,
|
[FromQuery] string? maxOfficialRating,
|
||||||
[FromQuery] bool? hasThemeSong,
|
[FromQuery] bool? hasThemeSong,
|
||||||
|
@ -244,21 +239,20 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableTotalRecordCount = true,
|
[FromQuery] bool enableTotalRecordCount = true,
|
||||||
[FromQuery] bool? enableImages = true)
|
[FromQuery] bool? enableImages = true)
|
||||||
{
|
{
|
||||||
var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
var isApiKey = User.GetIsApiKey();
|
||||||
|
|
||||||
// if api key is used (auth.IsApiKey == true), then `user` will be null throughout this method
|
// if api key is used (auth.IsApiKey == true), then `user` will be null throughout this method
|
||||||
var user = !auth.IsApiKey && userId.HasValue && !userId.Value.Equals(default)
|
var user = !isApiKey && userId.HasValue && !userId.Value.Equals(default)
|
||||||
? _userManager.GetUserById(userId.Value)
|
? _userManager.GetUserById(userId.Value)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
// beyond this point, we're either using an api key or we have a valid user
|
// beyond this point, we're either using an api key or we have a valid user
|
||||||
if (!auth.IsApiKey && user is null)
|
if (!isApiKey && user is null)
|
||||||
{
|
{
|
||||||
return BadRequest("userId is required");
|
return BadRequest("userId is required");
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
if (includeItemTypes.Length == 1
|
if (includeItemTypes.Length == 1
|
||||||
|
@ -288,12 +282,12 @@ namespace Jellyfin.Api.Controllers
|
||||||
includeItemTypes = new[] { BaseItemKind.Playlist };
|
includeItemTypes = new[] { BaseItemKind.Playlist };
|
||||||
}
|
}
|
||||||
|
|
||||||
var enabledChannels = auth.IsApiKey
|
var enabledChannels = isApiKey
|
||||||
? Array.Empty<Guid>()
|
? Array.Empty<Guid>()
|
||||||
: user!.GetPreferenceValues<Guid>(PreferenceKind.EnabledChannels);
|
: user!.GetPreferenceValues<Guid>(PreferenceKind.EnabledChannels);
|
||||||
|
|
||||||
// api keys are always enabled for all folders
|
// api keys are always enabled for all folders
|
||||||
bool isInEnabledFolder = auth.IsApiKey
|
bool isInEnabledFolder = isApiKey
|
||||||
|| Array.IndexOf(user!.GetPreferenceValues<Guid>(PreferenceKind.EnabledFolders), item.Id) != -1
|
|| Array.IndexOf(user!.GetPreferenceValues<Guid>(PreferenceKind.EnabledFolders), item.Id) != -1
|
||||||
// Assume all folders inside an EnabledChannel are enabled
|
// Assume all folders inside an EnabledChannel are enabled
|
||||||
|| Array.IndexOf(enabledChannels, item.Id) != -1
|
|| Array.IndexOf(enabledChannels, item.Id) != -1
|
||||||
|
@ -633,7 +627,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items.</returns>
|
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the items.</returns>
|
||||||
[HttpGet("Users/{userId}/Items")]
|
[HttpGet("Users/{userId}/Items")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public Task<ActionResult<QueryResult<BaseItemDto>>> GetItemsByUserId(
|
public ActionResult<QueryResult<BaseItemDto>> GetItemsByUserId(
|
||||||
[FromRoute] Guid userId,
|
[FromRoute] Guid userId,
|
||||||
[FromQuery] string? maxOfficialRating,
|
[FromQuery] string? maxOfficialRating,
|
||||||
[FromQuery] bool? hasThemeSong,
|
[FromQuery] bool? hasThemeSong,
|
||||||
|
@ -850,7 +844,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
var user = _userManager.GetUserById(userId);
|
var user = _userManager.GetUserById(userId);
|
||||||
var parentIdGuid = parentId ?? Guid.Empty;
|
var parentIdGuid = parentId ?? Guid.Empty;
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
var ancestorIds = Array.Empty<Guid>();
|
var ancestorIds = Array.Empty<Guid>();
|
||||||
|
|
|
@ -24,7 +24,6 @@ using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Entities.Movies;
|
using MediaBrowser.Controller.Entities.Movies;
|
||||||
using MediaBrowser.Controller.Entities.TV;
|
using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Model.Activity;
|
using MediaBrowser.Model.Activity;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
|
@ -50,7 +49,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly IDtoService _dtoService;
|
private readonly IDtoService _dtoService;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly IActivityManager _activityManager;
|
private readonly IActivityManager _activityManager;
|
||||||
private readonly ILocalizationManager _localization;
|
private readonly ILocalizationManager _localization;
|
||||||
private readonly ILibraryMonitor _libraryMonitor;
|
private readonly ILibraryMonitor _libraryMonitor;
|
||||||
|
@ -64,7 +62,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="activityManager">Instance of the <see cref="IActivityManager"/> interface.</param>
|
/// <param name="activityManager">Instance of the <see cref="IActivityManager"/> interface.</param>
|
||||||
/// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
|
/// <param name="localization">Instance of the <see cref="ILocalizationManager"/> interface.</param>
|
||||||
/// <param name="libraryMonitor">Instance of the <see cref="ILibraryMonitor"/> interface.</param>
|
/// <param name="libraryMonitor">Instance of the <see cref="ILibraryMonitor"/> interface.</param>
|
||||||
|
@ -75,7 +72,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IDtoService dtoService,
|
IDtoService dtoService,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
IActivityManager activityManager,
|
IActivityManager activityManager,
|
||||||
ILocalizationManager localization,
|
ILocalizationManager localization,
|
||||||
ILibraryMonitor libraryMonitor,
|
ILibraryMonitor libraryMonitor,
|
||||||
|
@ -86,7 +82,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_dtoService = dtoService;
|
_dtoService = dtoService;
|
||||||
_authContext = authContext;
|
|
||||||
_activityManager = activityManager;
|
_activityManager = activityManager;
|
||||||
_localization = localization;
|
_localization = localization;
|
||||||
_libraryMonitor = libraryMonitor;
|
_libraryMonitor = libraryMonitor;
|
||||||
|
@ -184,7 +179,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
item = parent;
|
item = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
var items = themeItems
|
var items = themeItems
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
|
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
@ -250,7 +245,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
item = parent;
|
item = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
var items = themeItems
|
var items = themeItems
|
||||||
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
|
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
@ -331,11 +326,10 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
public async Task<ActionResult> DeleteItem(Guid itemId)
|
public ActionResult DeleteItem(Guid itemId)
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(itemId);
|
var item = _libraryManager.GetItemById(itemId);
|
||||||
var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
var user = _userManager.GetUserById(User.GetUserId());
|
||||||
var user = auth.User;
|
|
||||||
|
|
||||||
if (!item.CanDelete(user))
|
if (!item.CanDelete(user))
|
||||||
{
|
{
|
||||||
|
@ -361,7 +355,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
|
||||||
public async Task<ActionResult> DeleteItems([FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] ids)
|
public ActionResult DeleteItems([FromQuery, ModelBinder(typeof(CommaDelimitedArrayModelBinder))] Guid[] ids)
|
||||||
{
|
{
|
||||||
if (ids.Length == 0)
|
if (ids.Length == 0)
|
||||||
{
|
{
|
||||||
|
@ -371,8 +365,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
foreach (var i in ids)
|
foreach (var i in ids)
|
||||||
{
|
{
|
||||||
var item = _libraryManager.GetItemById(i);
|
var item = _libraryManager.GetItemById(i);
|
||||||
var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
var user = _userManager.GetUserById(User.GetUserId());
|
||||||
var user = auth.User;
|
|
||||||
|
|
||||||
if (!item.CanDelete(user))
|
if (!item.CanDelete(user))
|
||||||
{
|
{
|
||||||
|
@ -453,7 +446,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
BaseItem? parent = item.GetParent();
|
BaseItem? parent = item.GetParent();
|
||||||
|
|
||||||
while (parent != null)
|
while (parent != null)
|
||||||
|
@ -505,7 +498,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
items = items.Where(i => i.IsHidden == val).ToList();
|
items = items.Where(i => i.IsHidden == val).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
var resultArray = _dtoService.GetBaseItemDtos(items, dtoOptions);
|
var resultArray = _dtoService.GetBaseItemDtos(items, dtoOptions);
|
||||||
return new QueryResult<BaseItemDto>(resultArray);
|
return new QueryResult<BaseItemDto>(resultArray);
|
||||||
}
|
}
|
||||||
|
@ -622,9 +615,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
var auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
var user = _userManager.GetUserById(User.GetUserId());
|
||||||
|
|
||||||
var user = auth.User;
|
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
|
@ -643,7 +634,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
await LogDownloadAsync(item, user, auth).ConfigureAwait(false);
|
await LogDownloadAsync(item, user).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
var path = item.Path;
|
var path = item.Path;
|
||||||
|
@ -704,7 +695,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request);
|
.AddClientFields(User);
|
||||||
|
|
||||||
var program = item as IHasProgramAttributes;
|
var program = item as IHasProgramAttributes;
|
||||||
bool? isMovie = item is Movie || (program != null && program.IsMovie) || item is Trailer;
|
bool? isMovie = item is Movie || (program != null && program.IsMovie) || item is Trailer;
|
||||||
|
@ -892,16 +883,16 @@ namespace Jellyfin.Api.Controllers
|
||||||
: item;
|
: item;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LogDownloadAsync(BaseItem item, User user, AuthorizationInfo auth)
|
private async Task LogDownloadAsync(BaseItem item, User user)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _activityManager.CreateAsync(new ActivityLog(
|
await _activityManager.CreateAsync(new ActivityLog(
|
||||||
string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Username, item.Name),
|
string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("UserDownloadingItemWithValues"), user.Username, item.Name),
|
||||||
"UserDownloadingContent",
|
"UserDownloadingContent",
|
||||||
auth.UserId)
|
User.GetUserId())
|
||||||
{
|
{
|
||||||
ShortOverview = string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("AppDeviceValues"), auth.Client, auth.Device),
|
ShortOverview = string.Format(CultureInfo.InvariantCulture, _localization.GetLocalizedString("AppDeviceValues"), User.GetClient(), User.GetDevice()),
|
||||||
}).ConfigureAwait(false);
|
}).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|
|
@ -17,6 +17,7 @@ using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Api.Models.LiveTvDtos;
|
using Jellyfin.Api.Models.LiveTvDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
@ -24,6 +25,7 @@ using MediaBrowser.Controller.Entities.TV;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.LiveTv;
|
using MediaBrowser.Controller.LiveTv;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Net;
|
||||||
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.LiveTv;
|
using MediaBrowser.Model.LiveTv;
|
||||||
|
@ -45,10 +47,10 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly IHttpClientFactory _httpClientFactory;
|
private readonly IHttpClientFactory _httpClientFactory;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IDtoService _dtoService;
|
private readonly IDtoService _dtoService;
|
||||||
private readonly ISessionContext _sessionContext;
|
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
private readonly IConfigurationManager _configurationManager;
|
private readonly IConfigurationManager _configurationManager;
|
||||||
private readonly TranscodingJobHelper _transcodingJobHelper;
|
private readonly TranscodingJobHelper _transcodingJobHelper;
|
||||||
|
private readonly ISessionManager _sessionManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="LiveTvController"/> class.
|
/// Initializes a new instance of the <see cref="LiveTvController"/> class.
|
||||||
|
@ -58,30 +60,30 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param>
|
/// <param name="httpClientFactory">Instance of the <see cref="IHttpClientFactory"/> interface.</param>
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
||||||
/// <param name="sessionContext">Instance of the <see cref="ISessionContext"/> interface.</param>
|
|
||||||
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
/// <param name="configurationManager">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
/// <param name="configurationManager">Instance of the <see cref="IConfigurationManager"/> interface.</param>
|
||||||
/// <param name="transcodingJobHelper">Instance of the <see cref="TranscodingJobHelper"/> class.</param>
|
/// <param name="transcodingJobHelper">Instance of the <see cref="TranscodingJobHelper"/> class.</param>
|
||||||
|
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||||
public LiveTvController(
|
public LiveTvController(
|
||||||
ILiveTvManager liveTvManager,
|
ILiveTvManager liveTvManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IHttpClientFactory httpClientFactory,
|
IHttpClientFactory httpClientFactory,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IDtoService dtoService,
|
IDtoService dtoService,
|
||||||
ISessionContext sessionContext,
|
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IConfigurationManager configurationManager,
|
IConfigurationManager configurationManager,
|
||||||
TranscodingJobHelper transcodingJobHelper)
|
TranscodingJobHelper transcodingJobHelper,
|
||||||
|
ISessionManager sessionManager)
|
||||||
{
|
{
|
||||||
_liveTvManager = liveTvManager;
|
_liveTvManager = liveTvManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_httpClientFactory = httpClientFactory;
|
_httpClientFactory = httpClientFactory;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_dtoService = dtoService;
|
_dtoService = dtoService;
|
||||||
_sessionContext = sessionContext;
|
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_configurationManager = configurationManager;
|
_configurationManager = configurationManager;
|
||||||
_transcodingJobHelper = transcodingJobHelper;
|
_transcodingJobHelper = transcodingJobHelper;
|
||||||
|
_sessionManager = sessionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -154,7 +156,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool addCurrentProgram = true)
|
[FromQuery] bool addCurrentProgram = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
var channelResult = _liveTvManager.GetInternalChannels(
|
var channelResult = _liveTvManager.GetInternalChannels(
|
||||||
|
@ -219,7 +221,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
: _libraryManager.GetItemById(channelId);
|
: _libraryManager.GetItemById(channelId);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions()
|
var dtoOptions = new DtoOptions()
|
||||||
.AddClientFields(Request);
|
.AddClientFields(User);
|
||||||
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +274,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
return _liveTvManager.GetRecordings(
|
return _liveTvManager.GetRecordings(
|
||||||
|
@ -410,7 +412,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
var item = recordingId.Equals(default) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(recordingId);
|
var item = recordingId.Equals(default) ? _libraryManager.GetUserRootFolder() : _libraryManager.GetItemById(recordingId);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions()
|
var dtoOptions = new DtoOptions()
|
||||||
.AddClientFields(Request);
|
.AddClientFields(User);
|
||||||
|
|
||||||
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
||||||
}
|
}
|
||||||
|
@ -599,7 +601,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
|
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -653,7 +655,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = body.Fields }
|
var dtoOptions = new DtoOptions { Fields = body.Fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(body.EnableImages, body.EnableUserData, body.ImageTypeLimit, body.EnableImageTypes);
|
.AddAdditionalDtoOptions(body.EnableImages, body.EnableUserData, body.ImageTypeLimit, body.EnableImageTypes);
|
||||||
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
|
return await _liveTvManager.GetPrograms(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -719,7 +721,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
};
|
};
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
return await _liveTvManager.GetRecommendedProgramsAsync(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
|
return await _liveTvManager.GetRecommendedProgramsAsync(query, dtoOptions, CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -1210,9 +1212,16 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
private async Task AssertUserCanManageLiveTv()
|
private async Task AssertUserCanManageLiveTv()
|
||||||
{
|
{
|
||||||
var user = await _sessionContext.GetUser(Request).ConfigureAwait(false);
|
var user = _userManager.GetUserById(User.GetUserId());
|
||||||
|
var session = await _sessionManager.LogSessionActivity(
|
||||||
|
User.GetClient(),
|
||||||
|
User.GetVersion(),
|
||||||
|
User.GetDeviceId(),
|
||||||
|
User.GetDevice(),
|
||||||
|
HttpContext.GetNormalizedRemoteIp().ToString(),
|
||||||
|
user).ConfigureAwait(false);
|
||||||
|
|
||||||
if (user == null)
|
if (session.UserId.Equals(default))
|
||||||
{
|
{
|
||||||
throw new SecurityException("Anonymous live tv management is not allowed.");
|
throw new SecurityException("Anonymous live tv management is not allowed.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,12 @@ using System.Net.Mime;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Attributes;
|
using Jellyfin.Api.Attributes;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.Models.MediaInfoDtos;
|
using Jellyfin.Api.Models.MediaInfoDtos;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Devices;
|
using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
@ -31,7 +31,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
private readonly IDeviceManager _deviceManager;
|
private readonly IDeviceManager _deviceManager;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly ILogger<MediaInfoController> _logger;
|
private readonly ILogger<MediaInfoController> _logger;
|
||||||
private readonly MediaInfoHelper _mediaInfoHelper;
|
private readonly MediaInfoHelper _mediaInfoHelper;
|
||||||
|
|
||||||
|
@ -41,21 +40,18 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
/// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
|
/// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger{MediaInfoController}"/> interface.</param>
|
/// <param name="logger">Instance of the <see cref="ILogger{MediaInfoController}"/> interface.</param>
|
||||||
/// <param name="mediaInfoHelper">Instance of the <see cref="MediaInfoHelper"/>.</param>
|
/// <param name="mediaInfoHelper">Instance of the <see cref="MediaInfoHelper"/>.</param>
|
||||||
public MediaInfoController(
|
public MediaInfoController(
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IDeviceManager deviceManager,
|
IDeviceManager deviceManager,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
ILogger<MediaInfoController> logger,
|
ILogger<MediaInfoController> logger,
|
||||||
MediaInfoHelper mediaInfoHelper)
|
MediaInfoHelper mediaInfoHelper)
|
||||||
{
|
{
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_deviceManager = deviceManager;
|
_deviceManager = deviceManager;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_authContext = authContext;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_mediaInfoHelper = mediaInfoHelper;
|
_mediaInfoHelper = mediaInfoHelper;
|
||||||
}
|
}
|
||||||
|
@ -122,14 +118,12 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery, ParameterObsolete] bool? allowAudioStreamCopy,
|
[FromQuery, ParameterObsolete] bool? allowAudioStreamCopy,
|
||||||
[FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] PlaybackInfoDto? playbackInfoDto)
|
[FromBody(EmptyBodyBehavior = EmptyBodyBehavior.Allow)] PlaybackInfoDto? playbackInfoDto)
|
||||||
{
|
{
|
||||||
var authInfo = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
|
||||||
|
|
||||||
var profile = playbackInfoDto?.DeviceProfile;
|
var profile = playbackInfoDto?.DeviceProfile;
|
||||||
_logger.LogDebug("GetPostedPlaybackInfo profile: {@Profile}", profile);
|
_logger.LogDebug("GetPostedPlaybackInfo profile: {@Profile}", profile);
|
||||||
|
|
||||||
if (profile == null)
|
if (profile == null)
|
||||||
{
|
{
|
||||||
var caps = _deviceManager.GetCapabilities(authInfo.DeviceId);
|
var caps = _deviceManager.GetCapabilities(User.GetDeviceId());
|
||||||
if (caps != null)
|
if (caps != null)
|
||||||
{
|
{
|
||||||
profile = caps.DeviceProfile;
|
profile = caps.DeviceProfile;
|
||||||
|
@ -176,7 +170,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
item,
|
item,
|
||||||
mediaSource,
|
mediaSource,
|
||||||
profile,
|
profile,
|
||||||
authInfo,
|
User,
|
||||||
maxStreamingBitrate ?? profile.MaxStreamingBitrate,
|
maxStreamingBitrate ?? profile.MaxStreamingBitrate,
|
||||||
startTimeTicks ?? 0,
|
startTimeTicks ?? 0,
|
||||||
mediaSourceId ?? string.Empty,
|
mediaSourceId ?? string.Empty,
|
||||||
|
@ -203,7 +197,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
if (mediaSource != null && mediaSource.RequiresOpening && string.IsNullOrWhiteSpace(mediaSource.LiveStreamId))
|
if (mediaSource != null && mediaSource.RequiresOpening && string.IsNullOrWhiteSpace(mediaSource.LiveStreamId))
|
||||||
{
|
{
|
||||||
var openStreamResult = await _mediaInfoHelper.OpenMediaSource(
|
var openStreamResult = await _mediaInfoHelper.OpenMediaSource(
|
||||||
Request,
|
HttpContext,
|
||||||
new LiveStreamRequest
|
new LiveStreamRequest
|
||||||
{
|
{
|
||||||
AudioStreamIndex = audioStreamIndex,
|
AudioStreamIndex = audioStreamIndex,
|
||||||
|
@ -276,7 +270,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
EnableDirectStream = enableDirectStream ?? openLiveStreamDto?.EnableDirectStream ?? true,
|
EnableDirectStream = enableDirectStream ?? openLiveStreamDto?.EnableDirectStream ?? true,
|
||||||
DirectPlayProtocols = openLiveStreamDto?.DirectPlayProtocols ?? new[] { MediaProtocol.Http }
|
DirectPlayProtocols = openLiveStreamDto?.DirectPlayProtocols ?? new[] { MediaProtocol.Http }
|
||||||
};
|
};
|
||||||
return await _mediaInfoHelper.OpenMediaSource(Request, request).ConfigureAwait(false);
|
return await _mediaInfoHelper.OpenMediaSource(HttpContext, request).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId.Value);
|
: _userManager.GetUserById(userId.Value);
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request);
|
.AddClientFields(User);
|
||||||
|
|
||||||
var categories = new List<RecommendationDto>();
|
var categories = new List<RecommendationDto>();
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, false, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId is null || userId.Value.Equals(default)
|
User? user = userId is null || userId.Value.Equals(default)
|
||||||
|
@ -145,7 +145,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public ActionResult<BaseItemDto> GetMusicGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
|
public ActionResult<BaseItemDto> GetMusicGenre([FromRoute, Required] string genreName, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
MusicGenre? item;
|
MusicGenre? item;
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool? enableImages = true)
|
[FromQuery] bool? enableImages = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId is null || userId.Value.Equals(default)
|
User? user = userId is null || userId.Value.Equals(default)
|
||||||
|
@ -119,7 +119,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public ActionResult<BaseItemDto> GetPerson([FromRoute, Required] string name, [FromQuery] Guid? userId)
|
public ActionResult<BaseItemDto> GetPerson([FromRoute, Required] string name, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions()
|
var dtoOptions = new DtoOptions()
|
||||||
.AddClientFields(Request);
|
.AddClientFields(User);
|
||||||
|
|
||||||
var item = _libraryManager.GetPerson(name);
|
var item = _libraryManager.GetPerson(name);
|
||||||
if (item == null)
|
if (item == null)
|
||||||
|
|
|
@ -200,7 +200,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2).ToList(), dtoOptions, user);
|
var dtos = _dtoService.GetBaseItemDtos(items.Select(i => i.Item2).ToList(), dtoOptions, user);
|
||||||
|
|
|
@ -3,11 +3,11 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
|
@ -29,7 +29,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly IUserDataManager _userDataRepository;
|
private readonly IUserDataManager _userDataRepository;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly ILogger<PlaystateController> _logger;
|
private readonly ILogger<PlaystateController> _logger;
|
||||||
private readonly TranscodingJobHelper _transcodingJobHelper;
|
private readonly TranscodingJobHelper _transcodingJobHelper;
|
||||||
|
|
||||||
|
@ -40,7 +39,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="userDataRepository">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
/// <param name="userDataRepository">Instance of the <see cref="IUserDataManager"/> interface.</param>
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
||||||
/// <param name="transcodingJobHelper">Th <see cref="TranscodingJobHelper"/> singleton.</param>
|
/// <param name="transcodingJobHelper">Th <see cref="TranscodingJobHelper"/> singleton.</param>
|
||||||
public PlaystateController(
|
public PlaystateController(
|
||||||
|
@ -48,7 +46,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
IUserDataManager userDataRepository,
|
IUserDataManager userDataRepository,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
ILoggerFactory loggerFactory,
|
ILoggerFactory loggerFactory,
|
||||||
TranscodingJobHelper transcodingJobHelper)
|
TranscodingJobHelper transcodingJobHelper)
|
||||||
{
|
{
|
||||||
|
@ -56,7 +53,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
_userDataRepository = userDataRepository;
|
_userDataRepository = userDataRepository;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
_authContext = authContext;
|
|
||||||
_logger = loggerFactory.CreateLogger<PlaystateController>();
|
_logger = loggerFactory.CreateLogger<PlaystateController>();
|
||||||
|
|
||||||
_transcodingJobHelper = transcodingJobHelper;
|
_transcodingJobHelper = transcodingJobHelper;
|
||||||
|
@ -78,7 +74,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery, ModelBinder(typeof(LegacyDateTimeModelBinder))] DateTime? datePlayed)
|
[FromQuery, ModelBinder(typeof(LegacyDateTimeModelBinder))] DateTime? datePlayed)
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId);
|
var user = _userManager.GetUserById(userId);
|
||||||
var session = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
var session = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var dto = UpdatePlayedStatus(user, itemId, true, datePlayed);
|
var dto = UpdatePlayedStatus(user, itemId, true, datePlayed);
|
||||||
foreach (var additionalUserInfo in session.AdditionalUsers)
|
foreach (var additionalUserInfo in session.AdditionalUsers)
|
||||||
{
|
{
|
||||||
|
@ -101,7 +97,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult<UserItemDataDto>> MarkUnplayedItem([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
|
public async Task<ActionResult<UserItemDataDto>> MarkUnplayedItem([FromRoute, Required] Guid userId, [FromRoute, Required] Guid itemId)
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId);
|
var user = _userManager.GetUserById(userId);
|
||||||
var session = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
var session = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var dto = UpdatePlayedStatus(user, itemId, false, null);
|
var dto = UpdatePlayedStatus(user, itemId, false, null);
|
||||||
foreach (var additionalUserInfo in session.AdditionalUsers)
|
foreach (var additionalUserInfo in session.AdditionalUsers)
|
||||||
{
|
{
|
||||||
|
@ -123,7 +119,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> ReportPlaybackStart([FromBody] PlaybackStartInfo playbackStartInfo)
|
public async Task<ActionResult> ReportPlaybackStart([FromBody] PlaybackStartInfo playbackStartInfo)
|
||||||
{
|
{
|
||||||
playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
|
playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
|
||||||
playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
|
await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -139,7 +135,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> ReportPlaybackProgress([FromBody] PlaybackProgressInfo playbackProgressInfo)
|
public async Task<ActionResult> ReportPlaybackProgress([FromBody] PlaybackProgressInfo playbackProgressInfo)
|
||||||
{
|
{
|
||||||
playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
|
playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
|
||||||
playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
|
await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -171,11 +167,10 @@ namespace Jellyfin.Api.Controllers
|
||||||
_logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
|
_logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
|
||||||
if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
|
if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
|
||||||
{
|
{
|
||||||
var authInfo = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
await _transcodingJobHelper.KillTranscodingJobs(User.GetDeviceId()!, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
|
||||||
await _transcodingJobHelper.KillTranscodingJobs(authInfo.DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
|
await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -221,7 +216,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
};
|
};
|
||||||
|
|
||||||
playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
|
playbackStartInfo.PlayMethod = ValidatePlayMethod(playbackStartInfo.PlayMethod, playbackStartInfo.PlaySessionId);
|
||||||
playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
playbackStartInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
|
await _sessionManager.OnPlaybackStart(playbackStartInfo).ConfigureAwait(false);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -279,7 +274,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
};
|
};
|
||||||
|
|
||||||
playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
|
playbackProgressInfo.PlayMethod = ValidatePlayMethod(playbackProgressInfo.PlayMethod, playbackProgressInfo.PlaySessionId);
|
||||||
playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
playbackProgressInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);;
|
||||||
await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
|
await _sessionManager.OnPlaybackProgress(playbackProgressInfo).ConfigureAwait(false);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -321,11 +316,10 @@ namespace Jellyfin.Api.Controllers
|
||||||
_logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
|
_logger.LogDebug("ReportPlaybackStopped PlaySessionId: {0}", playbackStopInfo.PlaySessionId ?? string.Empty);
|
||||||
if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
|
if (!string.IsNullOrWhiteSpace(playbackStopInfo.PlaySessionId))
|
||||||
{
|
{
|
||||||
var authInfo = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
await _transcodingJobHelper.KillTranscodingJobs(User.GetDeviceId()!, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
|
||||||
await _transcodingJobHelper.KillTranscodingJobs(authInfo.DeviceId, playbackStopInfo.PlaySessionId, s => true).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
playbackStopInfo.SessionId = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);;
|
||||||
await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
|
await _sessionManager.OnPlaybackStopped(playbackStopInfo).ConfigureAwait(false);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Authentication;
|
using MediaBrowser.Controller.Authentication;
|
||||||
|
@ -104,15 +105,15 @@ namespace Jellyfin.Api.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
[ProducesResponseType(StatusCodes.Status403Forbidden)]
|
||||||
public async Task<ActionResult<bool>> AuthorizeQuickConnect([FromQuery, Required] string code)
|
public async Task<ActionResult<bool>> AuthorizeQuickConnect([FromQuery, Required] string code)
|
||||||
{
|
{
|
||||||
var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
|
var userId = User.GetUserId();
|
||||||
if (!userId.HasValue)
|
if (userId.Equals(default))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "Unknown user id");
|
return StatusCode(StatusCodes.Status403Forbidden, "Unknown user id");
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await _quickConnect.AuthorizeRequest(userId.Value, code).ConfigureAwait(false);
|
return await _quickConnect.AuthorizeRequest(userId, code).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (AuthenticationException)
|
catch (AuthenticationException)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,13 +5,13 @@ using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Api.Models.SessionDtos;
|
using Jellyfin.Api.Models.SessionDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Controller.Devices;
|
using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Session;
|
using MediaBrowser.Model.Session;
|
||||||
|
@ -29,7 +29,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
{
|
{
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly IDeviceManager _deviceManager;
|
private readonly IDeviceManager _deviceManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -37,17 +36,14 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sessionManager">Instance of <see cref="ISessionManager"/> interface.</param>
|
/// <param name="sessionManager">Instance of <see cref="ISessionManager"/> interface.</param>
|
||||||
/// <param name="userManager">Instance of <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="deviceManager">Instance of <see cref="IDeviceManager"/> interface.</param>
|
/// <param name="deviceManager">Instance of <see cref="IDeviceManager"/> interface.</param>
|
||||||
public SessionController(
|
public SessionController(
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
IDeviceManager deviceManager)
|
IDeviceManager deviceManager)
|
||||||
{
|
{
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_authContext = authContext;
|
|
||||||
_deviceManager = deviceManager;
|
_deviceManager = deviceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +135,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
};
|
};
|
||||||
|
|
||||||
await _sessionManager.SendBrowseCommand(
|
await _sessionManager.SendBrowseCommand(
|
||||||
await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
|
await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
|
||||||
sessionId,
|
sessionId,
|
||||||
command,
|
command,
|
||||||
CancellationToken.None)
|
CancellationToken.None)
|
||||||
|
@ -186,7 +182,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
};
|
};
|
||||||
|
|
||||||
await _sessionManager.SendPlayCommand(
|
await _sessionManager.SendPlayCommand(
|
||||||
await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
|
await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
|
||||||
sessionId,
|
sessionId,
|
||||||
playRequest,
|
playRequest,
|
||||||
CancellationToken.None)
|
CancellationToken.None)
|
||||||
|
@ -214,7 +210,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] string? controllingUserId)
|
[FromQuery] string? controllingUserId)
|
||||||
{
|
{
|
||||||
await _sessionManager.SendPlaystateCommand(
|
await _sessionManager.SendPlaystateCommand(
|
||||||
await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
|
await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
|
||||||
sessionId,
|
sessionId,
|
||||||
new PlaystateRequest()
|
new PlaystateRequest()
|
||||||
{
|
{
|
||||||
|
@ -242,14 +238,14 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] string sessionId,
|
[FromRoute, Required] string sessionId,
|
||||||
[FromRoute, Required] GeneralCommandType command)
|
[FromRoute, Required] GeneralCommandType command)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var generalCommand = new GeneralCommand
|
var generalCommand = new GeneralCommand
|
||||||
{
|
{
|
||||||
Name = command,
|
Name = command,
|
||||||
ControllingUserId = currentSession.UserId
|
ControllingUserId = currentSession.UserId
|
||||||
};
|
};
|
||||||
|
|
||||||
await _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None);
|
await _sessionManager.SendGeneralCommand(currentSession.Id, sessionId, generalCommand, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
@ -268,7 +264,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] string sessionId,
|
[FromRoute, Required] string sessionId,
|
||||||
[FromRoute, Required] GeneralCommandType command)
|
[FromRoute, Required] GeneralCommandType command)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
|
|
||||||
var generalCommand = new GeneralCommand
|
var generalCommand = new GeneralCommand
|
||||||
{
|
{
|
||||||
|
@ -296,8 +292,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] string sessionId,
|
[FromRoute, Required] string sessionId,
|
||||||
[FromBody, Required] GeneralCommand command)
|
[FromBody, Required] GeneralCommand command)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authContext, Request)
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (command == null)
|
if (command == null)
|
||||||
{
|
{
|
||||||
|
@ -336,7 +331,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
await _sessionManager.SendMessageCommand(
|
await _sessionManager.SendMessageCommand(
|
||||||
await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false),
|
await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false),
|
||||||
sessionId,
|
sessionId,
|
||||||
command,
|
command,
|
||||||
CancellationToken.None)
|
CancellationToken.None)
|
||||||
|
@ -405,7 +400,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(id))
|
if (string.IsNullOrWhiteSpace(id))
|
||||||
{
|
{
|
||||||
id = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
id = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_sessionManager.ReportCapabilities(id, new ClientCapabilities
|
_sessionManager.ReportCapabilities(id, new ClientCapabilities
|
||||||
|
@ -435,7 +430,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(id))
|
if (string.IsNullOrWhiteSpace(id))
|
||||||
{
|
{
|
||||||
id = await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
id = await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_sessionManager.ReportCapabilities(id, capabilities.ToClientCapabilities());
|
_sessionManager.ReportCapabilities(id, capabilities.ToClientCapabilities());
|
||||||
|
@ -457,7 +452,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] string? sessionId,
|
[FromQuery] string? sessionId,
|
||||||
[FromQuery, Required] string? itemId)
|
[FromQuery, Required] string? itemId)
|
||||||
{
|
{
|
||||||
string session = sessionId ?? await RequestHelpers.GetSessionId(_sessionManager, _authContext, Request).ConfigureAwait(false);
|
string session = sessionId ?? await RequestHelpers.GetSessionId(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
|
|
||||||
_sessionManager.ReportNowViewingItem(session, itemId);
|
_sessionManager.ReportNowViewingItem(session, itemId);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -473,9 +468,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||||
public async Task<ActionResult> ReportSessionEnded()
|
public async Task<ActionResult> ReportSessionEnded()
|
||||||
{
|
{
|
||||||
AuthorizationInfo auth = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
await _sessionManager.Logout(User.GetToken()).ConfigureAwait(false);
|
||||||
|
|
||||||
await _sessionManager.Logout(auth.Token).ConfigureAwait(false);
|
|
||||||
return NoContent();
|
return NoContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableTotalRecordCount = true)
|
[FromQuery] bool enableTotalRecordCount = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId is null || userId.Value.Equals(default)
|
User? user = userId is null || userId.Value.Equals(default)
|
||||||
|
@ -140,7 +140,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public ActionResult<BaseItemDto> GetStudio([FromRoute, Required] string name, [FromQuery] Guid? userId)
|
public ActionResult<BaseItemDto> GetStudio([FromRoute, Required] string name, [FromQuery] Guid? userId)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
var item = _libraryManager.GetStudio(name);
|
var item = _libraryManager.GetStudio(name);
|
||||||
if (userId.HasValue && !userId.Equals(default))
|
if (userId.HasValue && !userId.Equals(default))
|
||||||
|
|
|
@ -11,13 +11,13 @@ using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Attributes;
|
using Jellyfin.Api.Attributes;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Models.SubtitleDtos;
|
using Jellyfin.Api.Models.SubtitleDtos;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Providers;
|
using MediaBrowser.Controller.Providers;
|
||||||
using MediaBrowser.Controller.Subtitles;
|
using MediaBrowser.Controller.Subtitles;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -45,7 +45,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
private readonly IProviderManager _providerManager;
|
private readonly IProviderManager _providerManager;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly ILogger<SubtitleController> _logger;
|
private readonly ILogger<SubtitleController> _logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -58,7 +57,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="mediaSourceManager">Instance of <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
/// <param name="providerManager">Instance of <see cref="IProviderManager"/> interface.</param>
|
/// <param name="providerManager">Instance of <see cref="IProviderManager"/> interface.</param>
|
||||||
/// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
|
/// <param name="fileSystem">Instance of <see cref="IFileSystem"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="logger">Instance of <see cref="ILogger{SubtitleController}"/> interface.</param>
|
/// <param name="logger">Instance of <see cref="ILogger{SubtitleController}"/> interface.</param>
|
||||||
public SubtitleController(
|
public SubtitleController(
|
||||||
IServerConfigurationManager serverConfigurationManager,
|
IServerConfigurationManager serverConfigurationManager,
|
||||||
|
@ -68,7 +66,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IProviderManager providerManager,
|
IProviderManager providerManager,
|
||||||
IFileSystem fileSystem,
|
IFileSystem fileSystem,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
ILogger<SubtitleController> logger)
|
ILogger<SubtitleController> logger)
|
||||||
{
|
{
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
|
@ -78,7 +75,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_providerManager = providerManager;
|
_providerManager = providerManager;
|
||||||
_fileSystem = fileSystem;
|
_fileSystem = fileSystem;
|
||||||
_authContext = authContext;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -361,7 +357,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
long positionTicks = 0;
|
long positionTicks = 0;
|
||||||
|
|
||||||
var accessToken = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).Token;
|
var accessToken = User.GetToken();
|
||||||
|
|
||||||
while (positionTicks < runtime)
|
while (positionTicks < runtime)
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,7 +67,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? null
|
? null
|
||||||
: _userManager.GetUserById(userId);
|
: _userManager.GetUserById(userId);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
var result = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
|
var result = _libraryManager.GetItemsResult(new InternalItemsQuery(user)
|
||||||
{
|
{
|
||||||
OrderBy = new[] { (ItemSortBy.Random, SortOrder.Descending) },
|
OrderBy = new[] { (ItemSortBy.Random, SortOrder.Descending) },
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.Models.SyncPlayDtos;
|
using Jellyfin.Api.Models.SyncPlayDtos;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Controller.SyncPlay;
|
using MediaBrowser.Controller.SyncPlay;
|
||||||
using MediaBrowser.Controller.SyncPlay.PlaybackRequests;
|
using MediaBrowser.Controller.SyncPlay.PlaybackRequests;
|
||||||
|
@ -24,23 +24,23 @@ namespace Jellyfin.Api.Controllers
|
||||||
public class SyncPlayController : BaseJellyfinApiController
|
public class SyncPlayController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
private readonly IAuthorizationContext _authorizationContext;
|
|
||||||
private readonly ISyncPlayManager _syncPlayManager;
|
private readonly ISyncPlayManager _syncPlayManager;
|
||||||
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SyncPlayController"/> class.
|
/// Initializes a new instance of the <see cref="SyncPlayController"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||||
/// <param name="authorizationContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="syncPlayManager">Instance of the <see cref="ISyncPlayManager"/> interface.</param>
|
/// <param name="syncPlayManager">Instance of the <see cref="ISyncPlayManager"/> interface.</param>
|
||||||
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
public SyncPlayController(
|
public SyncPlayController(
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
IAuthorizationContext authorizationContext,
|
ISyncPlayManager syncPlayManager,
|
||||||
ISyncPlayManager syncPlayManager)
|
IUserManager userManager)
|
||||||
{
|
{
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
_authorizationContext = authorizationContext;
|
|
||||||
_syncPlayManager = syncPlayManager;
|
_syncPlayManager = syncPlayManager;
|
||||||
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -55,7 +55,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayCreateGroup(
|
public async Task<ActionResult> SyncPlayCreateGroup(
|
||||||
[FromBody, Required] NewGroupRequestDto requestData)
|
[FromBody, Required] NewGroupRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new NewGroupRequest(requestData.GroupName);
|
var syncPlayRequest = new NewGroupRequest(requestData.GroupName);
|
||||||
_syncPlayManager.NewGroup(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.NewGroup(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -73,7 +73,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayJoinGroup(
|
public async Task<ActionResult> SyncPlayJoinGroup(
|
||||||
[FromBody, Required] JoinGroupRequestDto requestData)
|
[FromBody, Required] JoinGroupRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new JoinGroupRequest(requestData.GroupId);
|
var syncPlayRequest = new JoinGroupRequest(requestData.GroupId);
|
||||||
_syncPlayManager.JoinGroup(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.JoinGroup(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -89,7 +89,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
||||||
public async Task<ActionResult> SyncPlayLeaveGroup()
|
public async Task<ActionResult> SyncPlayLeaveGroup()
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new LeaveGroupRequest();
|
var syncPlayRequest = new LeaveGroupRequest();
|
||||||
_syncPlayManager.LeaveGroup(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.LeaveGroup(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -105,7 +105,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Authorize(Policy = Policies.SyncPlayJoinGroup)]
|
[Authorize(Policy = Policies.SyncPlayJoinGroup)]
|
||||||
public async Task<ActionResult<IEnumerable<GroupInfoDto>>> SyncPlayGetGroups()
|
public async Task<ActionResult<IEnumerable<GroupInfoDto>>> SyncPlayGetGroups()
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new ListGroupsRequest();
|
var syncPlayRequest = new ListGroupsRequest();
|
||||||
return Ok(_syncPlayManager.ListGroups(currentSession, syncPlayRequest));
|
return Ok(_syncPlayManager.ListGroups(currentSession, syncPlayRequest));
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlaySetNewQueue(
|
public async Task<ActionResult> SyncPlaySetNewQueue(
|
||||||
[FromBody, Required] PlayRequestDto requestData)
|
[FromBody, Required] PlayRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new PlayGroupRequest(
|
var syncPlayRequest = new PlayGroupRequest(
|
||||||
requestData.PlayingQueue,
|
requestData.PlayingQueue,
|
||||||
requestData.PlayingItemPosition,
|
requestData.PlayingItemPosition,
|
||||||
|
@ -143,7 +143,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlaySetPlaylistItem(
|
public async Task<ActionResult> SyncPlaySetPlaylistItem(
|
||||||
[FromBody, Required] SetPlaylistItemRequestDto requestData)
|
[FromBody, Required] SetPlaylistItemRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new SetPlaylistItemGroupRequest(requestData.PlaylistItemId);
|
var syncPlayRequest = new SetPlaylistItemGroupRequest(requestData.PlaylistItemId);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayRemoveFromPlaylist(
|
public async Task<ActionResult> SyncPlayRemoveFromPlaylist(
|
||||||
[FromBody, Required] RemoveFromPlaylistRequestDto requestData)
|
[FromBody, Required] RemoveFromPlaylistRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new RemoveFromPlaylistGroupRequest(requestData.PlaylistItemIds, requestData.ClearPlaylist, requestData.ClearPlayingItem);
|
var syncPlayRequest = new RemoveFromPlaylistGroupRequest(requestData.PlaylistItemIds, requestData.ClearPlaylist, requestData.ClearPlayingItem);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -179,7 +179,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayMovePlaylistItem(
|
public async Task<ActionResult> SyncPlayMovePlaylistItem(
|
||||||
[FromBody, Required] MovePlaylistItemRequestDto requestData)
|
[FromBody, Required] MovePlaylistItemRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new MovePlaylistItemGroupRequest(requestData.PlaylistItemId, requestData.NewIndex);
|
var syncPlayRequest = new MovePlaylistItemGroupRequest(requestData.PlaylistItemId, requestData.NewIndex);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -197,7 +197,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayQueue(
|
public async Task<ActionResult> SyncPlayQueue(
|
||||||
[FromBody, Required] QueueRequestDto requestData)
|
[FromBody, Required] QueueRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new QueueGroupRequest(requestData.ItemIds, requestData.Mode);
|
var syncPlayRequest = new QueueGroupRequest(requestData.ItemIds, requestData.Mode);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -213,7 +213,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
||||||
public async Task<ActionResult> SyncPlayUnpause()
|
public async Task<ActionResult> SyncPlayUnpause()
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new UnpauseGroupRequest();
|
var syncPlayRequest = new UnpauseGroupRequest();
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -229,7 +229,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
||||||
public async Task<ActionResult> SyncPlayPause()
|
public async Task<ActionResult> SyncPlayPause()
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new PauseGroupRequest();
|
var syncPlayRequest = new PauseGroupRequest();
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -245,7 +245,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
[Authorize(Policy = Policies.SyncPlayIsInGroup)]
|
||||||
public async Task<ActionResult> SyncPlayStop()
|
public async Task<ActionResult> SyncPlayStop()
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new StopGroupRequest();
|
var syncPlayRequest = new StopGroupRequest();
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -263,7 +263,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlaySeek(
|
public async Task<ActionResult> SyncPlaySeek(
|
||||||
[FromBody, Required] SeekRequestDto requestData)
|
[FromBody, Required] SeekRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new SeekGroupRequest(requestData.PositionTicks);
|
var syncPlayRequest = new SeekGroupRequest(requestData.PositionTicks);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -281,7 +281,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayBuffering(
|
public async Task<ActionResult> SyncPlayBuffering(
|
||||||
[FromBody, Required] BufferRequestDto requestData)
|
[FromBody, Required] BufferRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new BufferGroupRequest(
|
var syncPlayRequest = new BufferGroupRequest(
|
||||||
requestData.When,
|
requestData.When,
|
||||||
requestData.PositionTicks,
|
requestData.PositionTicks,
|
||||||
|
@ -303,7 +303,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayReady(
|
public async Task<ActionResult> SyncPlayReady(
|
||||||
[FromBody, Required] ReadyRequestDto requestData)
|
[FromBody, Required] ReadyRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new ReadyGroupRequest(
|
var syncPlayRequest = new ReadyGroupRequest(
|
||||||
requestData.When,
|
requestData.When,
|
||||||
requestData.PositionTicks,
|
requestData.PositionTicks,
|
||||||
|
@ -325,7 +325,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlaySetIgnoreWait(
|
public async Task<ActionResult> SyncPlaySetIgnoreWait(
|
||||||
[FromBody, Required] IgnoreWaitRequestDto requestData)
|
[FromBody, Required] IgnoreWaitRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new IgnoreWaitGroupRequest(requestData.IgnoreWait);
|
var syncPlayRequest = new IgnoreWaitGroupRequest(requestData.IgnoreWait);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -343,7 +343,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayNextItem(
|
public async Task<ActionResult> SyncPlayNextItem(
|
||||||
[FromBody, Required] NextItemRequestDto requestData)
|
[FromBody, Required] NextItemRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new NextItemGroupRequest(requestData.PlaylistItemId);
|
var syncPlayRequest = new NextItemGroupRequest(requestData.PlaylistItemId);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -361,7 +361,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayPreviousItem(
|
public async Task<ActionResult> SyncPlayPreviousItem(
|
||||||
[FromBody, Required] PreviousItemRequestDto requestData)
|
[FromBody, Required] PreviousItemRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new PreviousItemGroupRequest(requestData.PlaylistItemId);
|
var syncPlayRequest = new PreviousItemGroupRequest(requestData.PlaylistItemId);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -379,7 +379,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlaySetRepeatMode(
|
public async Task<ActionResult> SyncPlaySetRepeatMode(
|
||||||
[FromBody, Required] SetRepeatModeRequestDto requestData)
|
[FromBody, Required] SetRepeatModeRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new SetRepeatModeGroupRequest(requestData.Mode);
|
var syncPlayRequest = new SetRepeatModeGroupRequest(requestData.Mode);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -397,7 +397,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlaySetShuffleMode(
|
public async Task<ActionResult> SyncPlaySetShuffleMode(
|
||||||
[FromBody, Required] SetShuffleModeRequestDto requestData)
|
[FromBody, Required] SetShuffleModeRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new SetShuffleModeGroupRequest(requestData.Mode);
|
var syncPlayRequest = new SetShuffleModeGroupRequest(requestData.Mode);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
@ -414,7 +414,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
public async Task<ActionResult> SyncPlayPing(
|
public async Task<ActionResult> SyncPlayPing(
|
||||||
[FromBody, Required] PingRequestDto requestData)
|
[FromBody, Required] PingRequestDto requestData)
|
||||||
{
|
{
|
||||||
var currentSession = await RequestHelpers.GetSession(_sessionManager, _authorizationContext, Request).ConfigureAwait(false);
|
var currentSession = await RequestHelpers.GetSession(_sessionManager, _userManager, HttpContext).ConfigureAwait(false);
|
||||||
var syncPlayRequest = new PingGroupRequest(requestData.Ping);
|
var syncPlayRequest = new PingGroupRequest(requestData.Ping);
|
||||||
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
_syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None);
|
||||||
return NoContent();
|
return NoContent();
|
||||||
|
|
|
@ -119,7 +119,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the trailers.</returns>
|
/// <returns>A <see cref="QueryResult{BaseItemDto}"/> with the trailers.</returns>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public Task<ActionResult<QueryResult<BaseItemDto>>> GetTrailers(
|
public ActionResult<QueryResult<BaseItemDto>> GetTrailers(
|
||||||
[FromQuery] Guid? userId,
|
[FromQuery] Guid? userId,
|
||||||
[FromQuery] string? maxOfficialRating,
|
[FromQuery] string? maxOfficialRating,
|
||||||
[FromQuery] bool? hasThemeSong,
|
[FromQuery] bool? hasThemeSong,
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableRewatching = false)
|
[FromQuery] bool enableRewatching = false)
|
||||||
{
|
{
|
||||||
var options = new DtoOptions { Fields = fields }
|
var options = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
var result = _tvSeriesManager.GetNextUp(
|
var result = _tvSeriesManager.GetNextUp(
|
||||||
|
@ -154,7 +154,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
var parentIdGuid = parentId ?? Guid.Empty;
|
var parentIdGuid = parentId ?? Guid.Empty;
|
||||||
|
|
||||||
var options = new DtoOptions { Fields = fields }
|
var options = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
var itemsResult = _libraryManager.GetItemList(new InternalItemsQuery(user)
|
||||||
|
@ -223,7 +223,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
List<BaseItem> episodes;
|
List<BaseItem> episodes;
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
if (seasonId.HasValue) // Season id was supplied. Get episodes by season id.
|
if (seasonId.HasValue) // Season id was supplied. Get episodes by season id.
|
||||||
|
@ -349,7 +349,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
});
|
});
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
var returnItems = _dtoService.GetBaseItemDtos(seasons, dtoOptions, user);
|
var returnItems = _dtoService.GetBaseItemDtos(seasons, dtoOptions, user);
|
||||||
|
|
|
@ -6,13 +6,13 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Attributes;
|
using Jellyfin.Api.Attributes;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.ModelBinders;
|
using Jellyfin.Api.ModelBinders;
|
||||||
using Jellyfin.Api.Models.StreamingDtos;
|
using Jellyfin.Api.Models.StreamingDtos;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
@ -28,7 +28,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
[Route("")]
|
[Route("")]
|
||||||
public class UniversalAudioController : BaseJellyfinApiController
|
public class UniversalAudioController : BaseJellyfinApiController
|
||||||
{
|
{
|
||||||
private readonly IAuthorizationContext _authorizationContext;
|
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ILogger<UniversalAudioController> _logger;
|
private readonly ILogger<UniversalAudioController> _logger;
|
||||||
private readonly MediaInfoHelper _mediaInfoHelper;
|
private readonly MediaInfoHelper _mediaInfoHelper;
|
||||||
|
@ -38,21 +37,18 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="UniversalAudioController"/> class.
|
/// Initializes a new instance of the <see cref="UniversalAudioController"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="authorizationContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger{UniversalAudioController}"/> interface.</param>
|
/// <param name="logger">Instance of the <see cref="ILogger{UniversalAudioController}"/> interface.</param>
|
||||||
/// <param name="mediaInfoHelper">Instance of <see cref="MediaInfoHelper"/>.</param>
|
/// <param name="mediaInfoHelper">Instance of <see cref="MediaInfoHelper"/>.</param>
|
||||||
/// <param name="audioHelper">Instance of <see cref="AudioHelper"/>.</param>
|
/// <param name="audioHelper">Instance of <see cref="AudioHelper"/>.</param>
|
||||||
/// <param name="dynamicHlsHelper">Instance of <see cref="DynamicHlsHelper"/>.</param>
|
/// <param name="dynamicHlsHelper">Instance of <see cref="DynamicHlsHelper"/>.</param>
|
||||||
public UniversalAudioController(
|
public UniversalAudioController(
|
||||||
IAuthorizationContext authorizationContext,
|
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
ILogger<UniversalAudioController> logger,
|
ILogger<UniversalAudioController> logger,
|
||||||
MediaInfoHelper mediaInfoHelper,
|
MediaInfoHelper mediaInfoHelper,
|
||||||
AudioHelper audioHelper,
|
AudioHelper audioHelper,
|
||||||
DynamicHlsHelper dynamicHlsHelper)
|
DynamicHlsHelper dynamicHlsHelper)
|
||||||
{
|
{
|
||||||
_authorizationContext = authorizationContext;
|
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_mediaInfoHelper = mediaInfoHelper;
|
_mediaInfoHelper = mediaInfoHelper;
|
||||||
|
@ -111,16 +107,12 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool enableRedirection = true)
|
[FromQuery] bool enableRedirection = true)
|
||||||
{
|
{
|
||||||
var deviceProfile = GetDeviceProfile(container, transcodingContainer, audioCodec, transcodingProtocol, breakOnNonKeyFrames, transcodingAudioChannels, maxAudioSampleRate, maxAudioBitDepth, maxAudioChannels);
|
var deviceProfile = GetDeviceProfile(container, transcodingContainer, audioCodec, transcodingProtocol, breakOnNonKeyFrames, transcodingAudioChannels, maxAudioSampleRate, maxAudioBitDepth, maxAudioChannels);
|
||||||
var authorizationInfo = await _authorizationContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
|
||||||
authorizationInfo.DeviceId = deviceId;
|
|
||||||
|
|
||||||
if (!userId.HasValue || userId.Value.Equals(Guid.Empty))
|
if (!userId.HasValue || userId.Value.Equals(Guid.Empty))
|
||||||
{
|
{
|
||||||
userId = authorizationInfo.UserId;
|
userId = User.GetUserId();
|
||||||
}
|
}
|
||||||
|
|
||||||
var authInfo = await _authorizationContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
|
|
||||||
|
|
||||||
_logger.LogInformation("GetPostedPlaybackInfo profile: {@Profile}", deviceProfile);
|
_logger.LogInformation("GetPostedPlaybackInfo profile: {@Profile}", deviceProfile);
|
||||||
|
|
||||||
var info = await _mediaInfoHelper.GetPlaybackInfo(
|
var info = await _mediaInfoHelper.GetPlaybackInfo(
|
||||||
|
@ -138,7 +130,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
item,
|
item,
|
||||||
sourceInfo,
|
sourceInfo,
|
||||||
deviceProfile,
|
deviceProfile,
|
||||||
authInfo,
|
User,
|
||||||
maxStreamingBitrate ?? deviceProfile.MaxStreamingBitrate,
|
maxStreamingBitrate ?? deviceProfile.MaxStreamingBitrate,
|
||||||
startTimeTicks ?? 0,
|
startTimeTicks ?? 0,
|
||||||
mediaSourceId ?? string.Empty,
|
mediaSourceId ?? string.Empty,
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.ComponentModel.DataAnnotations;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Jellyfin.Api.Constants;
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Helpers;
|
using Jellyfin.Api.Helpers;
|
||||||
using Jellyfin.Api.Models.UserDtos;
|
using Jellyfin.Api.Models.UserDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
@ -82,11 +83,11 @@ namespace Jellyfin.Api.Controllers
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<IEnumerable<UserDto>>> GetUsers(
|
public ActionResult<IEnumerable<UserDto>> GetUsers(
|
||||||
[FromQuery] bool? isHidden,
|
[FromQuery] bool? isHidden,
|
||||||
[FromQuery] bool? isDisabled)
|
[FromQuery] bool? isDisabled)
|
||||||
{
|
{
|
||||||
var users = await Get(isHidden, isDisabled, false, false).ConfigureAwait(false);
|
var users = Get(isHidden, isDisabled, false, false);
|
||||||
return Ok(users);
|
return Ok(users);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,15 +98,15 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <returns>An <see cref="IEnumerable{UserDto}"/> containing the public users.</returns>
|
/// <returns>An <see cref="IEnumerable{UserDto}"/> containing the public users.</returns>
|
||||||
[HttpGet("Public")]
|
[HttpGet("Public")]
|
||||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<IEnumerable<UserDto>>> GetPublicUsers()
|
public ActionResult<IEnumerable<UserDto>> GetPublicUsers()
|
||||||
{
|
{
|
||||||
// If the startup wizard hasn't been completed then just return all users
|
// If the startup wizard hasn't been completed then just return all users
|
||||||
if (!_config.Configuration.IsStartupWizardCompleted)
|
if (!_config.Configuration.IsStartupWizardCompleted)
|
||||||
{
|
{
|
||||||
return Ok(await Get(false, false, false, false).ConfigureAwait(false));
|
return Ok(Get(false, false, false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(await Get(false, false, true, true).ConfigureAwait(false));
|
return Ok(Get(false, false, true, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -264,7 +265,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] Guid userId,
|
[FromRoute, Required] Guid userId,
|
||||||
[FromBody, Required] UpdateUserPassword request)
|
[FromBody, Required] UpdateUserPassword request)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the password.");
|
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the password.");
|
||||||
}
|
}
|
||||||
|
@ -282,7 +283,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!HttpContext.User.IsInRole(UserRoles.Administrator))
|
if (!User.IsInRole(UserRoles.Administrator))
|
||||||
{
|
{
|
||||||
var success = await _userManager.AuthenticateUser(
|
var success = await _userManager.AuthenticateUser(
|
||||||
user.Username,
|
user.Username,
|
||||||
|
@ -299,7 +300,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
await _userManager.ChangePassword(user, request.NewPw).ConfigureAwait(false);
|
await _userManager.ChangePassword(user, request.NewPw).ConfigureAwait(false);
|
||||||
|
|
||||||
var currentToken = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).Token;
|
var currentToken = User.GetToken();
|
||||||
|
|
||||||
await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false);
|
await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
@ -325,7 +326,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] Guid userId,
|
[FromRoute, Required] Guid userId,
|
||||||
[FromBody, Required] UpdateUserEasyPassword request)
|
[FromBody, Required] UpdateUserEasyPassword request)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, true).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the easy password.");
|
return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update the easy password.");
|
||||||
}
|
}
|
||||||
|
@ -367,7 +368,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] Guid userId,
|
[FromRoute, Required] Guid userId,
|
||||||
[FromBody, Required] UserDto updateUser)
|
[FromBody, Required] UserDto updateUser)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, false).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User update not allowed.");
|
return StatusCode(StatusCodes.Status403Forbidden, "User update not allowed.");
|
||||||
}
|
}
|
||||||
|
@ -427,7 +428,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "There must be at least one enabled user in the system.");
|
return StatusCode(StatusCodes.Status403Forbidden, "There must be at least one enabled user in the system.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentToken = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).Token;
|
var currentToken = User.GetToken();
|
||||||
await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false);
|
await _sessionManager.RevokeUserTokens(user.Id, currentToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +453,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromRoute, Required] Guid userId,
|
[FromRoute, Required] Guid userId,
|
||||||
[FromBody, Required] UserConfiguration userConfig)
|
[FromBody, Required] UserConfiguration userConfig)
|
||||||
{
|
{
|
||||||
if (!await RequestHelpers.AssertCanUpdateUser(_authContext, HttpContext.Request, userId, false).ConfigureAwait(false))
|
if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
|
||||||
{
|
{
|
||||||
return StatusCode(StatusCodes.Status403Forbidden, "User configuration update not allowed");
|
return StatusCode(StatusCodes.Status403Forbidden, "User configuration update not allowed");
|
||||||
}
|
}
|
||||||
|
@ -536,13 +537,13 @@ namespace Jellyfin.Api.Controllers
|
||||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
public ActionResult<UserDto> GetCurrentUser()
|
public ActionResult<UserDto> GetCurrentUser()
|
||||||
{
|
{
|
||||||
var userId = ClaimHelpers.GetUserId(Request.HttpContext.User);
|
var userId = User.GetUserId();
|
||||||
if (userId is null)
|
if (userId.Equals(default))
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = _userManager.GetUserById(userId.Value);
|
var user = _userManager.GetUserById(userId);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest();
|
||||||
|
@ -551,7 +552,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
return _userManager.GetUserDto(user);
|
return _userManager.GetUserDto(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<IEnumerable<UserDto>> Get(bool? isHidden, bool? isDisabled, bool filterByDevice, bool filterByNetwork)
|
private IEnumerable<UserDto> Get(bool? isHidden, bool? isDisabled, bool filterByDevice, bool filterByNetwork)
|
||||||
{
|
{
|
||||||
var users = _userManager.Users;
|
var users = _userManager.Users;
|
||||||
|
|
||||||
|
@ -567,7 +568,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
if (filterByDevice)
|
if (filterByDevice)
|
||||||
{
|
{
|
||||||
var deviceId = (await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false)).DeviceId;
|
var deviceId = User.GetDeviceId();
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(deviceId))
|
if (!string.IsNullOrWhiteSpace(deviceId))
|
||||||
{
|
{
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
await RefreshItemOnDemandIfNeeded(item).ConfigureAwait(false);
|
await RefreshItemOnDemandIfNeeded(item).ConfigureAwait(false);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
{
|
{
|
||||||
var user = _userManager.GetUserById(userId);
|
var user = _userManager.GetUserById(userId);
|
||||||
var item = _libraryManager.GetUserRootFolder();
|
var item = _libraryManager.GetUserRootFolder();
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
return _dtoService.GetBaseItemDto(item, dtoOptions, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
var items = await _libraryManager.GetIntros(item, user).ConfigureAwait(false);
|
var items = await _libraryManager.GetIntros(item, user).ConfigureAwait(false);
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray();
|
var dtos = items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray();
|
||||||
|
|
||||||
return new QueryResult<BaseItemDto>(dtos);
|
return new QueryResult<BaseItemDto>(dtos);
|
||||||
|
@ -200,7 +200,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
if (item is IHasTrailers hasTrailers)
|
if (item is IHasTrailers hasTrailers)
|
||||||
{
|
{
|
||||||
|
@ -230,7 +230,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
? _libraryManager.GetUserRootFolder()
|
? _libraryManager.GetUserRootFolder()
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
|
|
||||||
return Ok(item
|
return Ok(item
|
||||||
.GetExtras()
|
.GetExtras()
|
||||||
|
@ -280,7 +280,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
var list = _userViewManager.GetLatestItems(
|
var list = _userViewManager.GetLatestItems(
|
||||||
|
|
|
@ -85,7 +85,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
var folders = _userViewManager.GetUserViews(query);
|
var folders = _userViewManager.GetUserViews(query);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
var dtoOptions = new DtoOptions().AddClientFields(User);
|
||||||
var fields = dtoOptions.Fields.ToList();
|
var fields = dtoOptions.Fields.ToList();
|
||||||
|
|
||||||
fields.Add(ItemFields.PrimaryImageAspectRatio);
|
fields.Add(ItemFields.PrimaryImageAspectRatio);
|
||||||
|
|
|
@ -43,7 +43,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly IDtoService _dtoService;
|
private readonly IDtoService _dtoService;
|
||||||
private readonly IDlnaManager _dlnaManager;
|
private readonly IDlnaManager _dlnaManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
private readonly IServerConfigurationManager _serverConfigurationManager;
|
private readonly IServerConfigurationManager _serverConfigurationManager;
|
||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
|
@ -61,7 +60,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
|
||||||
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
||||||
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
||||||
|
@ -74,7 +72,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IDtoService dtoService,
|
IDtoService dtoService,
|
||||||
IDlnaManager dlnaManager,
|
IDlnaManager dlnaManager,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IServerConfigurationManager serverConfigurationManager,
|
IServerConfigurationManager serverConfigurationManager,
|
||||||
IMediaEncoder mediaEncoder,
|
IMediaEncoder mediaEncoder,
|
||||||
|
@ -87,7 +84,6 @@ namespace Jellyfin.Api.Controllers
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_dtoService = dtoService;
|
_dtoService = dtoService;
|
||||||
_dlnaManager = dlnaManager;
|
_dlnaManager = dlnaManager;
|
||||||
_authContext = authContext;
|
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
|
@ -120,7 +116,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
: _libraryManager.GetItemById(itemId);
|
: _libraryManager.GetItemById(itemId);
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions();
|
var dtoOptions = new DtoOptions();
|
||||||
dtoOptions = dtoOptions.AddClientFields(Request);
|
dtoOptions = dtoOptions.AddClientFields(User);
|
||||||
|
|
||||||
BaseItemDto[] items;
|
BaseItemDto[] items;
|
||||||
if (item is Video video)
|
if (item is Video video)
|
||||||
|
@ -429,8 +425,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
|
|
||||||
var state = await StreamingHelpers.GetStreamingState(
|
var state = await StreamingHelpers.GetStreamingState(
|
||||||
streamingRequest,
|
streamingRequest,
|
||||||
Request,
|
HttpContext,
|
||||||
_authContext,
|
|
||||||
_mediaSourceManager,
|
_mediaSourceManager,
|
||||||
_userManager,
|
_userManager,
|
||||||
_libraryManager,
|
_libraryManager,
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
[FromQuery] bool? enableImages = true)
|
[FromQuery] bool? enableImages = true)
|
||||||
{
|
{
|
||||||
var dtoOptions = new DtoOptions { Fields = fields }
|
var dtoOptions = new DtoOptions { Fields = fields }
|
||||||
.AddClientFields(Request)
|
.AddClientFields(User)
|
||||||
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
|
||||||
|
|
||||||
User? user = userId is null || userId.Value.Equals(default)
|
User? user = userId is null || userId.Value.Equals(default)
|
||||||
|
@ -179,7 +179,7 @@ namespace Jellyfin.Api.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
var dtoOptions = new DtoOptions()
|
var dtoOptions = new DtoOptions()
|
||||||
.AddClientFields(Request);
|
.AddClientFields(User);
|
||||||
|
|
||||||
if (userId.HasValue && !userId.Value.Equals(default))
|
if (userId.HasValue && !userId.Value.Equals(default))
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Jellyfin.Api.Constants;
|
||||||
|
|
||||||
|
namespace Jellyfin.Api.Extensions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extensions for <see cref="ClaimsPrincipal"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static class ClaimsPrincipalExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get user id from claims.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">Current claims principal.</param>
|
||||||
|
/// <returns>User id.</returns>
|
||||||
|
public static Guid GetUserId(this ClaimsPrincipal user)
|
||||||
|
{
|
||||||
|
var value = GetClaimValue(user, InternalClaimTypes.UserId);
|
||||||
|
return string.IsNullOrEmpty(value)
|
||||||
|
? default
|
||||||
|
: Guid.Parse(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get device id from claims.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">Current claims principal.</param>
|
||||||
|
/// <returns>Device id.</returns>
|
||||||
|
public static string? GetDeviceId(this ClaimsPrincipal user)
|
||||||
|
=> GetClaimValue(user, InternalClaimTypes.DeviceId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get device from claims.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">Current claims principal.</param>
|
||||||
|
/// <returns>Device.</returns>
|
||||||
|
public static string? GetDevice(this ClaimsPrincipal user)
|
||||||
|
=> GetClaimValue(user, InternalClaimTypes.Device);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get client from claims.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">Current claims principal.</param>
|
||||||
|
/// <returns>Client.</returns>
|
||||||
|
public static string? GetClient(this ClaimsPrincipal user)
|
||||||
|
=> GetClaimValue(user, InternalClaimTypes.Client);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get version from claims.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">Current claims principal.</param>
|
||||||
|
/// <returns>Version.</returns>
|
||||||
|
public static string? GetVersion(this ClaimsPrincipal user)
|
||||||
|
=> GetClaimValue(user, InternalClaimTypes.Version);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get token from claims.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">Current claims principal.</param>
|
||||||
|
/// <returns>Token.</returns>
|
||||||
|
public static string? GetToken(this ClaimsPrincipal user)
|
||||||
|
=> GetClaimValue(user, InternalClaimTypes.Token);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a flag specifying whether the request is using an api key.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="user">Current claims principal.</param>
|
||||||
|
/// <returns>The flag specifying whether the request is using an api key.</returns>
|
||||||
|
public static bool GetIsApiKey(this ClaimsPrincipal user)
|
||||||
|
{
|
||||||
|
var claimValue = GetClaimValue(user, InternalClaimTypes.IsApiKey);
|
||||||
|
return !string.IsNullOrEmpty(claimValue)
|
||||||
|
&& bool.TryParse(claimValue, out var parsedClaimValue)
|
||||||
|
&& parsedClaimValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetClaimValue(in ClaimsPrincipal user, string name)
|
||||||
|
=> user.Claims.FirstOrDefault(claim => claim.Type.Equals(name, StringComparison.OrdinalIgnoreCase))?.Value;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Jellyfin.Api.Helpers;
|
using System.Security.Claims;
|
||||||
using Jellyfin.Extensions;
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -22,14 +22,14 @@ namespace Jellyfin.Api.Extensions
|
||||||
/// Legacy order: 2.
|
/// Legacy order: 2.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="dtoOptions">DtoOptions object.</param>
|
/// <param name="dtoOptions">DtoOptions object.</param>
|
||||||
/// <param name="request">Current request.</param>
|
/// <param name="user">Current claims principal.</param>
|
||||||
/// <returns>Modified DtoOptions object.</returns>
|
/// <returns>Modified DtoOptions object.</returns>
|
||||||
internal static DtoOptions AddClientFields(
|
internal static DtoOptions AddClientFields(
|
||||||
this DtoOptions dtoOptions, HttpRequest request)
|
this DtoOptions dtoOptions, ClaimsPrincipal user)
|
||||||
{
|
{
|
||||||
dtoOptions.Fields ??= Array.Empty<ItemFields>();
|
dtoOptions.Fields ??= Array.Empty<ItemFields>();
|
||||||
|
|
||||||
string? client = ClaimHelpers.GetClient(request.HttpContext.User);
|
string? client = user.GetClient();
|
||||||
|
|
||||||
// No client in claim
|
// No client in claim
|
||||||
if (string.IsNullOrEmpty(client))
|
if (string.IsNullOrEmpty(client))
|
||||||
|
|
|
@ -11,7 +11,6 @@ using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.MediaInfo;
|
using MediaBrowser.Model.MediaInfo;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
@ -25,7 +24,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
public class AudioHelper
|
public class AudioHelper
|
||||||
{
|
{
|
||||||
private readonly IDlnaManager _dlnaManager;
|
private readonly IDlnaManager _dlnaManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
|
@ -41,7 +39,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// Initializes a new instance of the <see cref="AudioHelper"/> class.
|
/// Initializes a new instance of the <see cref="AudioHelper"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
|
@ -54,7 +51,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
|
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
|
||||||
public AudioHelper(
|
public AudioHelper(
|
||||||
IDlnaManager dlnaManager,
|
IDlnaManager dlnaManager,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
|
@ -67,7 +63,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
EncodingHelper encodingHelper)
|
EncodingHelper encodingHelper)
|
||||||
{
|
{
|
||||||
_dlnaManager = dlnaManager;
|
_dlnaManager = dlnaManager;
|
||||||
_authContext = authContext;
|
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
|
@ -102,8 +97,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
|
|
||||||
using var state = await StreamingHelpers.GetStreamingState(
|
using var state = await StreamingHelpers.GetStreamingState(
|
||||||
streamingRequest,
|
streamingRequest,
|
||||||
_httpContextAccessor.HttpContext.Request,
|
_httpContextAccessor.HttpContext,
|
||||||
_authContext,
|
|
||||||
_mediaSourceManager,
|
_mediaSourceManager,
|
||||||
_userManager,
|
_userManager,
|
||||||
_libraryManager,
|
_libraryManager,
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Jellyfin.Api.Constants;
|
|
||||||
|
|
||||||
namespace Jellyfin.Api.Helpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Claim Helpers.
|
|
||||||
/// </summary>
|
|
||||||
public static class ClaimHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Get user id from claims.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">Current claims principal.</param>
|
|
||||||
/// <returns>User id.</returns>
|
|
||||||
public static Guid? GetUserId(in ClaimsPrincipal user)
|
|
||||||
{
|
|
||||||
var value = GetClaimValue(user, InternalClaimTypes.UserId);
|
|
||||||
return string.IsNullOrEmpty(value)
|
|
||||||
? null
|
|
||||||
: Guid.Parse(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get device id from claims.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">Current claims principal.</param>
|
|
||||||
/// <returns>Device id.</returns>
|
|
||||||
public static string? GetDeviceId(in ClaimsPrincipal user)
|
|
||||||
=> GetClaimValue(user, InternalClaimTypes.DeviceId);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get device from claims.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">Current claims principal.</param>
|
|
||||||
/// <returns>Device.</returns>
|
|
||||||
public static string? GetDevice(in ClaimsPrincipal user)
|
|
||||||
=> GetClaimValue(user, InternalClaimTypes.Device);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get client from claims.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">Current claims principal.</param>
|
|
||||||
/// <returns>Client.</returns>
|
|
||||||
public static string? GetClient(in ClaimsPrincipal user)
|
|
||||||
=> GetClaimValue(user, InternalClaimTypes.Client);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get version from claims.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">Current claims principal.</param>
|
|
||||||
/// <returns>Version.</returns>
|
|
||||||
public static string? GetVersion(in ClaimsPrincipal user)
|
|
||||||
=> GetClaimValue(user, InternalClaimTypes.Version);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get token from claims.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">Current claims principal.</param>
|
|
||||||
/// <returns>Token.</returns>
|
|
||||||
public static string? GetToken(in ClaimsPrincipal user)
|
|
||||||
=> GetClaimValue(user, InternalClaimTypes.Token);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a flag specifying whether the request is using an api key.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="user">Current claims principal.</param>
|
|
||||||
/// <returns>The flag specifying whether the request is using an api key.</returns>
|
|
||||||
public static bool GetIsApiKey(in ClaimsPrincipal user)
|
|
||||||
{
|
|
||||||
var claimValue = GetClaimValue(user, InternalClaimTypes.IsApiKey);
|
|
||||||
return !string.IsNullOrEmpty(claimValue)
|
|
||||||
&& bool.TryParse(claimValue, out var parsedClaimValue)
|
|
||||||
&& parsedClaimValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string? GetClaimValue(in ClaimsPrincipal user, string name)
|
|
||||||
{
|
|
||||||
return user?.Identities
|
|
||||||
.SelectMany(c => c.Claims)
|
|
||||||
.Where(claim => claim.Type.Equals(name, StringComparison.OrdinalIgnoreCase))
|
|
||||||
.Select(claim => claim.Value)
|
|
||||||
.FirstOrDefault();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,6 +7,7 @@ using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Models.StreamingDtos;
|
using Jellyfin.Api.Models.StreamingDtos;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Common.Net;
|
using MediaBrowser.Common.Net;
|
||||||
|
@ -15,7 +16,6 @@ using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Model.Net;
|
using MediaBrowser.Model.Net;
|
||||||
|
@ -34,7 +34,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly IUserManager _userManager;
|
private readonly IUserManager _userManager;
|
||||||
private readonly IDlnaManager _dlnaManager;
|
private readonly IDlnaManager _dlnaManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
private readonly IMediaSourceManager _mediaSourceManager;
|
private readonly IMediaSourceManager _mediaSourceManager;
|
||||||
private readonly IServerConfigurationManager _serverConfigurationManager;
|
private readonly IServerConfigurationManager _serverConfigurationManager;
|
||||||
private readonly IMediaEncoder _mediaEncoder;
|
private readonly IMediaEncoder _mediaEncoder;
|
||||||
|
@ -51,7 +50,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
/// <param name="dlnaManager">Instance of the <see cref="IDlnaManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
||||||
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
||||||
|
@ -65,7 +63,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
IDlnaManager dlnaManager,
|
IDlnaManager dlnaManager,
|
||||||
IAuthorizationContext authContext,
|
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IServerConfigurationManager serverConfigurationManager,
|
IServerConfigurationManager serverConfigurationManager,
|
||||||
IMediaEncoder mediaEncoder,
|
IMediaEncoder mediaEncoder,
|
||||||
|
@ -79,7 +76,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_dlnaManager = dlnaManager;
|
_dlnaManager = dlnaManager;
|
||||||
_authContext = authContext;
|
|
||||||
_mediaSourceManager = mediaSourceManager;
|
_mediaSourceManager = mediaSourceManager;
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
|
@ -128,8 +124,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
|
|
||||||
using var state = await StreamingHelpers.GetStreamingState(
|
using var state = await StreamingHelpers.GetStreamingState(
|
||||||
streamingRequest,
|
streamingRequest,
|
||||||
_httpContextAccessor.HttpContext.Request,
|
_httpContextAccessor.HttpContext,
|
||||||
_authContext,
|
|
||||||
_mediaSourceManager,
|
_mediaSourceManager,
|
||||||
_userManager,
|
_userManager,
|
||||||
_libraryManager,
|
_libraryManager,
|
||||||
|
@ -483,7 +478,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
state.Request.MediaSourceId,
|
state.Request.MediaSourceId,
|
||||||
stream.Index.ToString(CultureInfo.InvariantCulture),
|
stream.Index.ToString(CultureInfo.InvariantCulture),
|
||||||
30.ToString(CultureInfo.InvariantCulture),
|
30.ToString(CultureInfo.InvariantCulture),
|
||||||
ClaimHelpers.GetToken(user));
|
user.GetToken());
|
||||||
|
|
||||||
var line = string.Format(
|
var line = string.Format(
|
||||||
CultureInfo.InvariantCulture,
|
CultureInfo.InvariantCulture,
|
||||||
|
|
|
@ -2,9 +2,11 @@
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
|
@ -15,7 +17,6 @@ using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities.Audio;
|
using MediaBrowser.Controller.Entities.Audio;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -39,7 +40,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
private readonly ILogger<MediaInfoHelper> _logger;
|
private readonly ILogger<MediaInfoHelper> _logger;
|
||||||
private readonly INetworkManager _networkManager;
|
private readonly INetworkManager _networkManager;
|
||||||
private readonly IDeviceManager _deviceManager;
|
private readonly IDeviceManager _deviceManager;
|
||||||
private readonly IAuthorizationContext _authContext;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="MediaInfoHelper"/> class.
|
/// Initializes a new instance of the <see cref="MediaInfoHelper"/> class.
|
||||||
|
@ -52,7 +52,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <param name="logger">Instance of the <see cref="ILogger{MediaInfoHelper}"/> interface.</param>
|
/// <param name="logger">Instance of the <see cref="ILogger{MediaInfoHelper}"/> interface.</param>
|
||||||
/// <param name="networkManager">Instance of the <see cref="INetworkManager"/> interface.</param>
|
/// <param name="networkManager">Instance of the <see cref="INetworkManager"/> interface.</param>
|
||||||
/// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
|
/// <param name="deviceManager">Instance of the <see cref="IDeviceManager"/> interface.</param>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
public MediaInfoHelper(
|
public MediaInfoHelper(
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
|
@ -61,8 +60,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
IServerConfigurationManager serverConfigurationManager,
|
IServerConfigurationManager serverConfigurationManager,
|
||||||
ILogger<MediaInfoHelper> logger,
|
ILogger<MediaInfoHelper> logger,
|
||||||
INetworkManager networkManager,
|
INetworkManager networkManager,
|
||||||
IDeviceManager deviceManager,
|
IDeviceManager deviceManager)
|
||||||
IAuthorizationContext authContext)
|
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
@ -72,7 +70,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_networkManager = networkManager;
|
_networkManager = networkManager;
|
||||||
_deviceManager = deviceManager;
|
_deviceManager = deviceManager;
|
||||||
_authContext = authContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -147,7 +144,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <param name="item">Item to set data for.</param>
|
/// <param name="item">Item to set data for.</param>
|
||||||
/// <param name="mediaSource">Media source info.</param>
|
/// <param name="mediaSource">Media source info.</param>
|
||||||
/// <param name="profile">Device profile.</param>
|
/// <param name="profile">Device profile.</param>
|
||||||
/// <param name="auth">Authorization info.</param>
|
/// <param name="claimsPrincipal">Current claims principal.</param>
|
||||||
/// <param name="maxBitrate">Max bitrate.</param>
|
/// <param name="maxBitrate">Max bitrate.</param>
|
||||||
/// <param name="startTimeTicks">Start time ticks.</param>
|
/// <param name="startTimeTicks">Start time ticks.</param>
|
||||||
/// <param name="mediaSourceId">Media source id.</param>
|
/// <param name="mediaSourceId">Media source id.</param>
|
||||||
|
@ -166,7 +163,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
BaseItem item,
|
BaseItem item,
|
||||||
MediaSourceInfo mediaSource,
|
MediaSourceInfo mediaSource,
|
||||||
DeviceProfile profile,
|
DeviceProfile profile,
|
||||||
AuthorizationInfo auth,
|
ClaimsPrincipal claimsPrincipal,
|
||||||
int? maxBitrate,
|
int? maxBitrate,
|
||||||
long startTimeTicks,
|
long startTimeTicks,
|
||||||
string mediaSourceId,
|
string mediaSourceId,
|
||||||
|
@ -188,7 +185,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
{
|
{
|
||||||
MediaSources = new[] { mediaSource },
|
MediaSources = new[] { mediaSource },
|
||||||
Context = EncodingContext.Streaming,
|
Context = EncodingContext.Streaming,
|
||||||
DeviceId = auth.DeviceId,
|
DeviceId = claimsPrincipal.GetDeviceId(),
|
||||||
ItemId = item.Id,
|
ItemId = item.Id,
|
||||||
Profile = profile,
|
Profile = profile,
|
||||||
MaxAudioChannels = maxAudioChannels,
|
MaxAudioChannels = maxAudioChannels,
|
||||||
|
@ -290,7 +287,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
mediaSource.SupportsDirectPlay = false;
|
mediaSource.SupportsDirectPlay = false;
|
||||||
mediaSource.SupportsDirectStream = false;
|
mediaSource.SupportsDirectStream = false;
|
||||||
|
|
||||||
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
|
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", claimsPrincipal.GetToken()).TrimStart('-');
|
||||||
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
|
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
|
||||||
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
|
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
|
||||||
mediaSource.TranscodingContainer = streamInfo.Container;
|
mediaSource.TranscodingContainer = streamInfo.Container;
|
||||||
|
@ -301,7 +298,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
if (!mediaSource.SupportsDirectPlay && (mediaSource.SupportsTranscoding || mediaSource.SupportsDirectStream))
|
if (!mediaSource.SupportsDirectPlay && (mediaSource.SupportsTranscoding || mediaSource.SupportsDirectStream))
|
||||||
{
|
{
|
||||||
streamInfo.PlayMethod = PlayMethod.Transcode;
|
streamInfo.PlayMethod = PlayMethod.Transcode;
|
||||||
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
|
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", claimsPrincipal.GetToken()).TrimStart('-');
|
||||||
|
|
||||||
if (!allowVideoStreamCopy)
|
if (!allowVideoStreamCopy)
|
||||||
{
|
{
|
||||||
|
@ -316,7 +313,8 @@ namespace Jellyfin.Api.Helpers
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do this after the above so that StartPositionTicks is set
|
// Do this after the above so that StartPositionTicks is set
|
||||||
SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token);
|
// The token must not be null
|
||||||
|
SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, claimsPrincipal.GetToken()!);
|
||||||
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
|
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,19 +382,17 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Open media source.
|
/// Open media source.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="httpRequest">Http Request.</param>
|
/// <param name="httpContext">Http Context.</param>
|
||||||
/// <param name="request">Live stream request.</param>
|
/// <param name="request">Live stream request.</param>
|
||||||
/// <returns>A <see cref="Task"/> containing the <see cref="LiveStreamResponse"/>.</returns>
|
/// <returns>A <see cref="Task"/> containing the <see cref="LiveStreamResponse"/>.</returns>
|
||||||
public async Task<LiveStreamResponse> OpenMediaSource(HttpRequest httpRequest, LiveStreamRequest request)
|
public async Task<LiveStreamResponse> OpenMediaSource(HttpContext httpContext, LiveStreamRequest request)
|
||||||
{
|
{
|
||||||
var authInfo = await _authContext.GetAuthorizationInfo(httpRequest).ConfigureAwait(false);
|
|
||||||
|
|
||||||
var result = await _mediaSourceManager.OpenLiveStream(request, CancellationToken.None).ConfigureAwait(false);
|
var result = await _mediaSourceManager.OpenLiveStream(request, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
var profile = request.DeviceProfile;
|
var profile = request.DeviceProfile;
|
||||||
if (profile == null)
|
if (profile == null)
|
||||||
{
|
{
|
||||||
var clientCapabilities = _deviceManager.GetCapabilities(authInfo.DeviceId);
|
var clientCapabilities = _deviceManager.GetCapabilities(httpContext.User.GetDeviceId());
|
||||||
if (clientCapabilities != null)
|
if (clientCapabilities != null)
|
||||||
{
|
{
|
||||||
profile = clientCapabilities.DeviceProfile;
|
profile = clientCapabilities.DeviceProfile;
|
||||||
|
@ -411,7 +407,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
item,
|
item,
|
||||||
result.MediaSource,
|
result.MediaSource,
|
||||||
profile,
|
profile,
|
||||||
authInfo,
|
httpContext.User,
|
||||||
request.MaxStreamingBitrate,
|
request.MaxStreamingBitrate,
|
||||||
request.StartTimeTicks ?? 0,
|
request.StartTimeTicks ?? 0,
|
||||||
result.MediaSource.Id,
|
result.MediaSource.Id,
|
||||||
|
@ -425,7 +421,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
httpRequest.HttpContext.GetNormalizedRemoteIp());
|
httpContext.GetNormalizedRemoteIp());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Api.Constants;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Data.Entities;
|
using Jellyfin.Data.Entities;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
using MediaBrowser.Common.Extensions;
|
using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Dto;
|
using MediaBrowser.Controller.Dto;
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Net;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Querying;
|
using MediaBrowser.Model.Querying;
|
||||||
|
@ -55,37 +58,42 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the user can update an entry.
|
/// Checks if the user can update an entry.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="authContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
/// <param name="userManager">An instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="requestContext">The <see cref="HttpRequest"/>.</param>
|
/// <param name="claimsPrincipal">The <see cref="ClaimsPrincipal"/> for the current request.</param>
|
||||||
/// <param name="userId">The user id.</param>
|
/// <param name="userId">The user id.</param>
|
||||||
/// <param name="restrictUserPreferences">Whether to restrict the user preferences.</param>
|
/// <param name="restrictUserPreferences">Whether to restrict the user preferences.</param>
|
||||||
/// <returns>A <see cref="bool"/> whether the user can update the entry.</returns>
|
/// <returns>A <see cref="bool"/> whether the user can update the entry.</returns>
|
||||||
internal static async Task<bool> AssertCanUpdateUser(IAuthorizationContext authContext, HttpRequest requestContext, Guid userId, bool restrictUserPreferences)
|
internal static bool AssertCanUpdateUser(IUserManager userManager, ClaimsPrincipal claimsPrincipal, Guid userId, bool restrictUserPreferences)
|
||||||
{
|
{
|
||||||
var auth = await authContext.GetAuthorizationInfo(requestContext).ConfigureAwait(false);
|
var authenticatedUserId = claimsPrincipal.GetUserId();
|
||||||
|
var isAdministrator = claimsPrincipal.IsInRole(UserRoles.Administrator);
|
||||||
var authenticatedUser = auth.User;
|
|
||||||
|
|
||||||
// If they're going to update the record of another user, they must be an administrator
|
// If they're going to update the record of another user, they must be an administrator
|
||||||
if ((!userId.Equals(auth.UserId) && !authenticatedUser.HasPermission(PermissionKind.IsAdministrator))
|
if (!userId.Equals(authenticatedUserId) && !isAdministrator)
|
||||||
|| (restrictUserPreferences && !authenticatedUser.EnableUserPreferenceAccess))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO the EnableUserPreferenceAccess policy does not seem to be used elsewhere
|
||||||
|
if (!restrictUserPreferences || isAdministrator)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<SessionInfo> GetSession(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
|
var user = userManager.GetUserById(userId);
|
||||||
|
return user.EnableUserPreferenceAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static async Task<SessionInfo> GetSession(ISessionManager sessionManager, IUserManager userManager, HttpContext httpContext)
|
||||||
{
|
{
|
||||||
var authorization = await authContext.GetAuthorizationInfo(request).ConfigureAwait(false);
|
var userId = httpContext.User.GetUserId();
|
||||||
var user = authorization.User;
|
var user = userManager.GetUserById(userId);
|
||||||
var session = await sessionManager.LogSessionActivity(
|
var session = await sessionManager.LogSessionActivity(
|
||||||
authorization.Client,
|
httpContext.User.GetClient(),
|
||||||
authorization.Version,
|
httpContext.User.GetVersion(),
|
||||||
authorization.DeviceId,
|
httpContext.User.GetDeviceId(),
|
||||||
authorization.Device,
|
httpContext.User.GetDevice(),
|
||||||
request.HttpContext.GetNormalizedRemoteIp().ToString(),
|
httpContext.GetNormalizedRemoteIp().ToString(),
|
||||||
user).ConfigureAwait(false);
|
user).ConfigureAwait(false);
|
||||||
|
|
||||||
if (session == null)
|
if (session == null)
|
||||||
|
@ -96,9 +104,9 @@ namespace Jellyfin.Api.Helpers
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static async Task<string> GetSessionId(ISessionManager sessionManager, IAuthorizationContext authContext, HttpRequest request)
|
internal static async Task<string> GetSessionId(ISessionManager sessionManager, IUserManager userManager, HttpContext httpContext)
|
||||||
{
|
{
|
||||||
var session = await GetSession(sessionManager, authContext, request).ConfigureAwait(false);
|
var session = await GetSession(sessionManager, userManager, httpContext).ConfigureAwait(false);
|
||||||
|
|
||||||
return session.Id;
|
return session.Id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Models.StreamingDtos;
|
using Jellyfin.Api.Models.StreamingDtos;
|
||||||
using Jellyfin.Extensions;
|
using Jellyfin.Extensions;
|
||||||
using MediaBrowser.Common.Configuration;
|
using MediaBrowser.Common.Configuration;
|
||||||
|
@ -14,7 +15,6 @@ using MediaBrowser.Controller.Devices;
|
||||||
using MediaBrowser.Controller.Dlna;
|
using MediaBrowser.Controller.Dlna;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Dto;
|
using MediaBrowser.Model.Dto;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -33,8 +33,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// Gets the current streaming state.
|
/// Gets the current streaming state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="streamingRequest">The <see cref="StreamingRequestDto"/>.</param>
|
/// <param name="streamingRequest">The <see cref="StreamingRequestDto"/>.</param>
|
||||||
/// <param name="httpRequest">The <see cref="HttpRequest"/>.</param>
|
/// <param name="httpContext">The <see cref="HttpContext"/>.</param>
|
||||||
/// <param name="authorizationContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
/// <param name="mediaSourceManager">Instance of the <see cref="IMediaSourceManager"/> interface.</param>
|
||||||
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
|
||||||
|
@ -49,8 +48,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <returns>A <see cref="Task"/> containing the current <see cref="StreamState"/>.</returns>
|
/// <returns>A <see cref="Task"/> containing the current <see cref="StreamState"/>.</returns>
|
||||||
public static async Task<StreamState> GetStreamingState(
|
public static async Task<StreamState> GetStreamingState(
|
||||||
StreamingRequestDto streamingRequest,
|
StreamingRequestDto streamingRequest,
|
||||||
HttpRequest httpRequest,
|
HttpContext httpContext,
|
||||||
IAuthorizationContext authorizationContext,
|
|
||||||
IMediaSourceManager mediaSourceManager,
|
IMediaSourceManager mediaSourceManager,
|
||||||
IUserManager userManager,
|
IUserManager userManager,
|
||||||
ILibraryManager libraryManager,
|
ILibraryManager libraryManager,
|
||||||
|
@ -63,6 +61,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
TranscodingJobType transcodingJobType,
|
TranscodingJobType transcodingJobType,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
var httpRequest = httpContext.Request;
|
||||||
// Parse the DLNA time seek header
|
// Parse the DLNA time seek header
|
||||||
if (!streamingRequest.StartTimeTicks.HasValue)
|
if (!streamingRequest.StartTimeTicks.HasValue)
|
||||||
{
|
{
|
||||||
|
@ -101,10 +100,10 @@ namespace Jellyfin.Api.Helpers
|
||||||
EnableDlnaHeaders = enableDlnaHeaders
|
EnableDlnaHeaders = enableDlnaHeaders
|
||||||
};
|
};
|
||||||
|
|
||||||
var auth = await authorizationContext.GetAuthorizationInfo(httpRequest).ConfigureAwait(false);
|
var userId = httpContext.User.GetUserId();
|
||||||
if (!auth.UserId.Equals(default))
|
if (!userId.Equals(default))
|
||||||
{
|
{
|
||||||
state.User = userManager.GetUserById(auth.UserId);
|
state.User = userManager.GetUserById(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.IsVideoRequest && !string.IsNullOrWhiteSpace(state.Request.VideoCodec))
|
if (state.IsVideoRequest && !string.IsNullOrWhiteSpace(state.Request.VideoCodec))
|
||||||
|
|
|
@ -8,6 +8,7 @@ using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Jellyfin.Api.Extensions;
|
||||||
using Jellyfin.Api.Models.PlaybackDtos;
|
using Jellyfin.Api.Models.PlaybackDtos;
|
||||||
using Jellyfin.Api.Models.StreamingDtos;
|
using Jellyfin.Api.Models.StreamingDtos;
|
||||||
using Jellyfin.Data.Enums;
|
using Jellyfin.Data.Enums;
|
||||||
|
@ -17,7 +18,6 @@ using MediaBrowser.Common.Extensions;
|
||||||
using MediaBrowser.Controller.Configuration;
|
using MediaBrowser.Controller.Configuration;
|
||||||
using MediaBrowser.Controller.Library;
|
using MediaBrowser.Controller.Library;
|
||||||
using MediaBrowser.Controller.MediaEncoding;
|
using MediaBrowser.Controller.MediaEncoding;
|
||||||
using MediaBrowser.Controller.Net;
|
|
||||||
using MediaBrowser.Controller.Session;
|
using MediaBrowser.Controller.Session;
|
||||||
using MediaBrowser.Model.Dlna;
|
using MediaBrowser.Model.Dlna;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -46,7 +46,6 @@ namespace Jellyfin.Api.Helpers
|
||||||
|
|
||||||
private readonly IAttachmentExtractor _attachmentExtractor;
|
private readonly IAttachmentExtractor _attachmentExtractor;
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
private readonly IAuthorizationContext _authorizationContext;
|
|
||||||
private readonly EncodingHelper _encodingHelper;
|
private readonly EncodingHelper _encodingHelper;
|
||||||
private readonly IFileSystem _fileSystem;
|
private readonly IFileSystem _fileSystem;
|
||||||
private readonly ILogger<TranscodingJobHelper> _logger;
|
private readonly ILogger<TranscodingJobHelper> _logger;
|
||||||
|
@ -55,6 +54,7 @@ namespace Jellyfin.Api.Helpers
|
||||||
private readonly IServerConfigurationManager _serverConfigurationManager;
|
private readonly IServerConfigurationManager _serverConfigurationManager;
|
||||||
private readonly ISessionManager _sessionManager;
|
private readonly ISessionManager _sessionManager;
|
||||||
private readonly ILoggerFactory _loggerFactory;
|
private readonly ILoggerFactory _loggerFactory;
|
||||||
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TranscodingJobHelper"/> class.
|
/// Initializes a new instance of the <see cref="TranscodingJobHelper"/> class.
|
||||||
|
@ -67,9 +67,9 @@ namespace Jellyfin.Api.Helpers
|
||||||
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
/// <param name="mediaEncoder">Instance of the <see cref="IMediaEncoder"/> interface.</param>
|
||||||
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
/// <param name="serverConfigurationManager">Instance of the <see cref="IServerConfigurationManager"/> interface.</param>
|
||||||
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||||
/// <param name="authorizationContext">Instance of the <see cref="IAuthorizationContext"/> interface.</param>
|
|
||||||
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
|
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
|
||||||
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
/// <param name="loggerFactory">Instance of the <see cref="ILoggerFactory"/> interface.</param>
|
||||||
|
/// <param name="userManager">Instance of the <see cref="IUserManager"/> interface.</param>
|
||||||
public TranscodingJobHelper(
|
public TranscodingJobHelper(
|
||||||
IAttachmentExtractor attachmentExtractor,
|
IAttachmentExtractor attachmentExtractor,
|
||||||
IApplicationPaths appPaths,
|
IApplicationPaths appPaths,
|
||||||
|
@ -79,9 +79,9 @@ namespace Jellyfin.Api.Helpers
|
||||||
IMediaEncoder mediaEncoder,
|
IMediaEncoder mediaEncoder,
|
||||||
IServerConfigurationManager serverConfigurationManager,
|
IServerConfigurationManager serverConfigurationManager,
|
||||||
ISessionManager sessionManager,
|
ISessionManager sessionManager,
|
||||||
IAuthorizationContext authorizationContext,
|
|
||||||
EncodingHelper encodingHelper,
|
EncodingHelper encodingHelper,
|
||||||
ILoggerFactory loggerFactory)
|
ILoggerFactory loggerFactory,
|
||||||
|
IUserManager userManager)
|
||||||
{
|
{
|
||||||
_attachmentExtractor = attachmentExtractor;
|
_attachmentExtractor = attachmentExtractor;
|
||||||
_appPaths = appPaths;
|
_appPaths = appPaths;
|
||||||
|
@ -91,9 +91,9 @@ namespace Jellyfin.Api.Helpers
|
||||||
_mediaEncoder = mediaEncoder;
|
_mediaEncoder = mediaEncoder;
|
||||||
_serverConfigurationManager = serverConfigurationManager;
|
_serverConfigurationManager = serverConfigurationManager;
|
||||||
_sessionManager = sessionManager;
|
_sessionManager = sessionManager;
|
||||||
_authorizationContext = authorizationContext;
|
|
||||||
_encodingHelper = encodingHelper;
|
_encodingHelper = encodingHelper;
|
||||||
_loggerFactory = loggerFactory;
|
_loggerFactory = loggerFactory;
|
||||||
|
_userManager = userManager;
|
||||||
|
|
||||||
DeleteEncodedMediaCache();
|
DeleteEncodedMediaCache();
|
||||||
|
|
||||||
|
@ -512,8 +512,9 @@ namespace Jellyfin.Api.Helpers
|
||||||
|
|
||||||
if (state.VideoRequest != null && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
|
if (state.VideoRequest != null && !EncodingHelper.IsCopyCodec(state.OutputVideoCodec))
|
||||||
{
|
{
|
||||||
var auth = await _authorizationContext.GetAuthorizationInfo(request).ConfigureAwait(false);
|
var userId = request.HttpContext.User.GetUserId();
|
||||||
if (auth.User != null && !auth.User.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
|
var user = userId.Equals(default) ? null : _userManager.GetUserById(userId);
|
||||||
|
if (user != null && !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding))
|
||||||
{
|
{
|
||||||
this.OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
this.OnTranscodeFailedToStart(outputPath, transcodingJobType, state);
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ namespace Jellyfin.Drawing.Skia
|
||||||
/// <exception cref="SkiaCodecException">The file at the specified path could not be used to generate a codec.</exception>
|
/// <exception cref="SkiaCodecException">The file at the specified path could not be used to generate a codec.</exception>
|
||||||
public string GetImageBlurHash(int xComp, int yComp, string path)
|
public string GetImageBlurHash(int xComp, int yComp, string path)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(path, nameof(path));
|
ArgumentNullException.ThrowIfNull(path);
|
||||||
|
|
||||||
if (path.Length == 0)
|
if (path.Length == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,10 +29,7 @@ namespace Jellyfin.Drawing.Skia
|
||||||
/// <returns>The image format.</returns>
|
/// <returns>The image format.</returns>
|
||||||
public static SKEncodedImageFormat GetEncodedFormat(string outputPath)
|
public static SKEncodedImageFormat GetEncodedFormat(string outputPath)
|
||||||
{
|
{
|
||||||
if (outputPath == null)
|
ArgumentNullException.ThrowIfNull(outputPath);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(outputPath));
|
|
||||||
}
|
|
||||||
|
|
||||||
var ext = Path.GetExtension(outputPath);
|
var ext = Path.GetExtension(outputPath);
|
||||||
|
|
||||||
|
|
|
@ -77,8 +77,11 @@ namespace Jellyfin.Networking.Manager
|
||||||
#pragma warning disable CS8618 // Non-nullable field is uninitialized. : Values are set in UpdateSettings function. Compiler doesn't yet recognise this.
|
#pragma warning disable CS8618 // Non-nullable field is uninitialized. : Values are set in UpdateSettings function. Compiler doesn't yet recognise this.
|
||||||
public NetworkManager(IConfigurationManager configurationManager, ILogger<NetworkManager> logger)
|
public NetworkManager(IConfigurationManager configurationManager, ILogger<NetworkManager> logger)
|
||||||
{
|
{
|
||||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
ArgumentNullException.ThrowIfNull(logger);
|
||||||
_configurationManager = configurationManager ?? throw new ArgumentNullException(nameof(configurationManager));
|
ArgumentNullException.ThrowIfNull(configurationManager);
|
||||||
|
|
||||||
|
_logger = logger;
|
||||||
|
_configurationManager = configurationManager;
|
||||||
_initLock = new();
|
_initLock = new();
|
||||||
_interfaces = new List<IPData>();
|
_interfaces = new List<IPData>();
|
||||||
_macAddresses = new List<PhysicalAddress>();
|
_macAddresses = new List<PhysicalAddress>();
|
||||||
|
@ -497,7 +500,9 @@ namespace Jellyfin.Networking.Manager
|
||||||
/// <param name="configuration">The <see cref="NetworkConfiguration"/> to use.</param>
|
/// <param name="configuration">The <see cref="NetworkConfiguration"/> to use.</param>
|
||||||
public void UpdateSettings(object configuration)
|
public void UpdateSettings(object configuration)
|
||||||
{
|
{
|
||||||
NetworkConfiguration config = (NetworkConfiguration)configuration ?? throw new ArgumentNullException(nameof(configuration));
|
ArgumentNullException.ThrowIfNull(configuration);
|
||||||
|
|
||||||
|
var config = (NetworkConfiguration)configuration;
|
||||||
|
|
||||||
InitialiseLan(config);
|
InitialiseLan(config);
|
||||||
InitialiseRemote(config);
|
InitialiseRemote(config);
|
||||||
|
@ -826,10 +831,7 @@ namespace Jellyfin.Networking.Manager
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public bool IsInLocalNetwork(IPAddress address)
|
public bool IsInLocalNetwork(IPAddress address)
|
||||||
{
|
{
|
||||||
if (address == null)
|
ArgumentNullException.ThrowIfNull(address);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(address));
|
|
||||||
}
|
|
||||||
|
|
||||||
// See conversation at https://github.com/jellyfin/jellyfin/pull/3515.
|
// See conversation at https://github.com/jellyfin/jellyfin/pull/3515.
|
||||||
if (TrustAllIpv6Interfaces && address.AddressFamily == AddressFamily.InterNetworkV6)
|
if (TrustAllIpv6Interfaces && address.AddressFamily == AddressFamily.InterNetworkV6)
|
||||||
|
|
|
@ -201,10 +201,7 @@ namespace Jellyfin.Server.Implementations.Devices
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool CanAccessDevice(User user, string deviceId)
|
public bool CanAccessDevice(User user, string deviceId)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(deviceId))
|
if (string.IsNullOrEmpty(deviceId))
|
||||||
{
|
{
|
||||||
|
|
|
@ -130,10 +130,7 @@ namespace Jellyfin.Server.Implementations.Users
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task RenameUser(User user, string newName)
|
public async Task RenameUser(User user, string newName)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
ThrowIfInvalidUsername(newName);
|
ThrowIfInvalidUsername(newName);
|
||||||
|
|
||||||
|
@ -267,10 +264,7 @@ namespace Jellyfin.Server.Implementations.Users
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task ChangePassword(User user, string newPassword)
|
public async Task ChangePassword(User user, string newPassword)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
await GetAuthenticationProvider(user).ChangePassword(user, newPassword).ConfigureAwait(false);
|
await GetAuthenticationProvider(user).ChangePassword(user, newPassword).ConfigureAwait(false);
|
||||||
await UpdateUserAsync(user).ConfigureAwait(false);
|
await UpdateUserAsync(user).ConfigureAwait(false);
|
||||||
|
|
|
@ -69,8 +69,8 @@ namespace Jellyfin.Server.Infrastructure
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
protected override Task WriteFileAsync(ActionContext context, PhysicalFileResult result, RangeItemHeaderValue? range, long rangeLength)
|
protected override Task WriteFileAsync(ActionContext context, PhysicalFileResult result, RangeItemHeaderValue? range, long rangeLength)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(context, nameof(context));
|
ArgumentNullException.ThrowIfNull(context);
|
||||||
ArgumentNullException.ThrowIfNull(result, nameof(result));
|
ArgumentNullException.ThrowIfNull(result);
|
||||||
|
|
||||||
if (range != null && rangeLength == 0)
|
if (range != null && rangeLength == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,10 +28,7 @@ namespace MediaBrowser.Common.Net
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static bool IsIPv6LinkLocal(IPAddress address)
|
public static bool IsIPv6LinkLocal(IPAddress address)
|
||||||
{
|
{
|
||||||
if (address == null)
|
ArgumentNullException.ThrowIfNull(address);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(address));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (address.IsIPv4MappedToIPv6)
|
if (address.IsIPv4MappedToIPv6)
|
||||||
{
|
{
|
||||||
|
@ -75,10 +72,7 @@ namespace MediaBrowser.Common.Net
|
||||||
/// <returns>Byte CIDR representing the mask.</returns>
|
/// <returns>Byte CIDR representing the mask.</returns>
|
||||||
public static byte MaskToCidr(IPAddress mask)
|
public static byte MaskToCidr(IPAddress mask)
|
||||||
{
|
{
|
||||||
if (mask == null)
|
ArgumentNullException.ThrowIfNull(mask);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(mask));
|
|
||||||
}
|
|
||||||
|
|
||||||
byte cidrnet = 0;
|
byte cidrnet = 0;
|
||||||
if (!mask.Equals(IPAddress.Any))
|
if (!mask.Equals(IPAddress.Any))
|
||||||
|
|
|
@ -164,10 +164,7 @@ namespace MediaBrowser.Common.Plugins
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual void UpdateConfiguration(BasePluginConfiguration configuration)
|
public virtual void UpdateConfiguration(BasePluginConfiguration configuration)
|
||||||
{
|
{
|
||||||
if (configuration == null)
|
ArgumentNullException.ThrowIfNull(configuration);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(configuration));
|
|
||||||
}
|
|
||||||
|
|
||||||
Configuration = (TConfigurationType)configuration;
|
Configuration = (TConfigurationType)configuration;
|
||||||
|
|
||||||
|
|
|
@ -171,10 +171,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <exception cref="ArgumentNullException">Throws if child is null.</exception>
|
/// <exception cref="ArgumentNullException">Throws if child is null.</exception>
|
||||||
public void AddVirtualChild(BaseItem child)
|
public void AddVirtualChild(BaseItem child)
|
||||||
{
|
{
|
||||||
if (child == null)
|
ArgumentNullException.ThrowIfNull(child);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(child));
|
|
||||||
}
|
|
||||||
|
|
||||||
_virtualChildren.Add(child);
|
_virtualChildren.Add(child);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1101,10 +1101,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
private MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, BaseItem item, MediaSourceType type)
|
private MediaSourceInfo GetVersionInfo(bool enablePathSubstitution, BaseItem item, MediaSourceType type)
|
||||||
{
|
{
|
||||||
if (item == null)
|
ArgumentNullException.ThrowIfNull(item);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(item));
|
|
||||||
}
|
|
||||||
|
|
||||||
var protocol = item.PathProtocol;
|
var protocol = item.PathProtocol;
|
||||||
|
|
||||||
|
@ -1544,10 +1541,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <exception cref="ArgumentNullException">If user is null.</exception>
|
/// <exception cref="ArgumentNullException">If user is null.</exception>
|
||||||
public bool IsParentalAllowed(User user)
|
public bool IsParentalAllowed(User user)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsVisibleViaTags(user))
|
if (!IsVisibleViaTags(user))
|
||||||
{
|
{
|
||||||
|
@ -1667,10 +1661,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="user" /> is <c>null</c>.</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="user" /> is <c>null</c>.</exception>
|
||||||
public virtual bool IsVisible(User user)
|
public virtual bool IsVisible(User user)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
return IsParentalAllowed(user);
|
return IsParentalAllowed(user);
|
||||||
}
|
}
|
||||||
|
@ -1842,10 +1833,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
DateTime? datePlayed,
|
DateTime? datePlayed,
|
||||||
bool resetPosition)
|
bool resetPosition)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = UserDataManager.GetUserData(user, this);
|
var data = UserDataManager.GetUserData(user, this);
|
||||||
|
|
||||||
|
@ -1876,10 +1864,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <exception cref="ArgumentNullException">Throws if user is null.</exception>
|
/// <exception cref="ArgumentNullException">Throws if user is null.</exception>
|
||||||
public virtual void MarkUnplayed(User user)
|
public virtual void MarkUnplayed(User user)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = UserDataManager.GetUserData(user, this);
|
var data = UserDataManager.GetUserData(user, this);
|
||||||
|
|
||||||
|
@ -2110,10 +2095,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
/// <returns>Image index.</returns>
|
/// <returns>Image index.</returns>
|
||||||
public int GetImageIndex(ItemImageInfo image)
|
public int GetImageIndex(ItemImageInfo image)
|
||||||
{
|
{
|
||||||
if (image == null)
|
ArgumentNullException.ThrowIfNull(image);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(image));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (image.Type == ImageType.Chapter)
|
if (image.Type == ImageType.Chapter)
|
||||||
{
|
{
|
||||||
|
@ -2320,10 +2302,7 @@ namespace MediaBrowser.Controller.Entities
|
||||||
|
|
||||||
public virtual bool IsUnplayed(User user)
|
public virtual bool IsUnplayed(User user)
|
||||||
{
|
{
|
||||||
if (user == null)
|
ArgumentNullException.ThrowIfNull(user);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(user));
|
|
||||||
}
|
|
||||||
|
|
||||||
var userdata = UserDataManager.GetUserData(user, this);
|
var userdata = UserDataManager.GetUserData(user, this);
|
||||||
|
|
||||||
|
|
|
@ -71,15 +71,9 @@ namespace MediaBrowser.Controller.Entities
|
||||||
where T : BaseItem
|
where T : BaseItem
|
||||||
where TU : BaseItem
|
where TU : BaseItem
|
||||||
{
|
{
|
||||||
if (source == null)
|
ArgumentNullException.ThrowIfNull(source);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(source));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest == null)
|
ArgumentNullException.ThrowIfNull(dest);
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(dest));
|
|
||||||
}
|
|
||||||
|
|
||||||
var destProps = typeof(TU).GetProperties().Where(x => x.CanWrite).ToList();
|
var destProps = typeof(TU).GetProperties().Where(x => x.CanWrite).ToList();
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue