Merge pull request #12587 from Shadowghost/session-info-dto

This commit is contained in:
Cody Robibero
2024-09-19 09:04:01 -06:00
committed by GitHub
18 changed files with 863 additions and 347 deletions

View File

@@ -1,20 +1,31 @@
#nullable disable
#pragma warning disable CS1591
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
namespace MediaBrowser.Controller.Authentication
namespace MediaBrowser.Controller.Authentication;
/// <summary>
/// A class representing an authentication result.
/// </summary>
public class AuthenticationResult
{
public class AuthenticationResult
{
public UserDto User { get; set; }
/// <summary>
/// Gets or sets the user.
/// </summary>
public UserDto User { get; set; }
public SessionInfo SessionInfo { get; set; }
/// <summary>
/// Gets or sets the session info.
/// </summary>
public SessionInfoDto SessionInfo { get; set; }
public string AccessToken { get; set; }
/// <summary>
/// Gets or sets the access token.
/// </summary>
public string AccessToken { get; set; }
public string ServerId { get; set; }
}
/// <summary>
/// Gets or sets the server id.
/// </summary>
public string ServerId { get; set; }
}

View File

@@ -1,81 +1,117 @@
#nullable disable
#pragma warning disable CS1591
using System;
using System.Threading.Tasks;
using Jellyfin.Data.Dtos;
using Jellyfin.Data.Entities;
using Jellyfin.Data.Entities.Security;
using Jellyfin.Data.Events;
using Jellyfin.Data.Queries;
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Controller.Devices
namespace MediaBrowser.Controller.Devices;
/// <summary>
/// Device manager interface.
/// </summary>
public interface IDeviceManager
{
public interface IDeviceManager
{
event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
/// <summary>
/// Event handler for updated device options.
/// </summary>
event EventHandler<GenericEventArgs<Tuple<string, DeviceOptions>>> DeviceOptionsUpdated;
/// <summary>
/// Creates a new device.
/// </summary>
/// <param name="device">The device to create.</param>
/// <returns>A <see cref="Task{Device}"/> representing the creation of the device.</returns>
Task<Device> CreateDevice(Device device);
/// <summary>
/// Creates a new device.
/// </summary>
/// <param name="device">The device to create.</param>
/// <returns>A <see cref="Task{Device}"/> representing the creation of the device.</returns>
Task<Device> CreateDevice(Device device);
/// <summary>
/// Saves the capabilities.
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <param name="capabilities">The capabilities.</param>
void SaveCapabilities(string deviceId, ClientCapabilities capabilities);
/// <summary>
/// Saves the capabilities.
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <param name="capabilities">The capabilities.</param>
void SaveCapabilities(string deviceId, ClientCapabilities capabilities);
/// <summary>
/// Gets the capabilities.
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <returns>ClientCapabilities.</returns>
ClientCapabilities GetCapabilities(string deviceId);
/// <summary>
/// Gets the capabilities.
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <returns>ClientCapabilities.</returns>
ClientCapabilities GetCapabilities(string? deviceId);
/// <summary>
/// Gets the device information.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>DeviceInfo.</returns>
DeviceInfo GetDevice(string id);
/// <summary>
/// Gets the device information.
/// </summary>
/// <param name="id">The identifier.</param>
/// <returns>DeviceInfoDto.</returns>
DeviceInfoDto? GetDevice(string id);
/// <summary>
/// Gets devices based on the provided query.
/// </summary>
/// <param name="query">The device query.</param>
/// <returns>A <see cref="Task{QueryResult}"/> representing the retrieval of the devices.</returns>
QueryResult<Device> GetDevices(DeviceQuery query);
/// <summary>
/// Gets devices based on the provided query.
/// </summary>
/// <param name="query">The device query.</param>
/// <returns>A <see cref="Task{QueryResult}"/> representing the retrieval of the devices.</returns>
QueryResult<Device> GetDevices(DeviceQuery query);
QueryResult<DeviceInfo> GetDeviceInfos(DeviceQuery query);
/// <summary>
/// Gets device infromation based on the provided query.
/// </summary>
/// <param name="query">The device query.</param>
/// <returns>A <see cref="Task{QueryResult}"/> representing the retrieval of the device information.</returns>
QueryResult<DeviceInfo> GetDeviceInfos(DeviceQuery query);
/// <summary>
/// Gets the devices.
/// </summary>
/// <param name="userId">The user's id, or <c>null</c>.</param>
/// <returns>IEnumerable&lt;DeviceInfo&gt;.</returns>
QueryResult<DeviceInfo> GetDevicesForUser(Guid? userId);
/// <summary>
/// Gets the device information.
/// </summary>
/// <param name="userId">The user's id, or <c>null</c>.</param>
/// <returns>IEnumerable&lt;DeviceInfoDto&gt;.</returns>
QueryResult<DeviceInfoDto> GetDevicesForUser(Guid? userId);
Task DeleteDevice(Device device);
/// <summary>
/// Deletes a device.
/// </summary>
/// <param name="device">The device.</param>
/// <returns>A <see cref="Task"/> representing the deletion of the device.</returns>
Task DeleteDevice(Device device);
Task UpdateDevice(Device device);
/// <summary>
/// Updates a device.
/// </summary>
/// <param name="device">The device.</param>
/// <returns>A <see cref="Task"/> representing the update of the device.</returns>
Task UpdateDevice(Device device);
/// <summary>
/// Determines whether this instance [can access device] the specified user identifier.
/// </summary>
/// <param name="user">The user to test.</param>
/// <param name="deviceId">The device id to test.</param>
/// <returns>Whether the user can access the device.</returns>
bool CanAccessDevice(User user, string deviceId);
/// <summary>
/// Determines whether this instance [can access device] the specified user identifier.
/// </summary>
/// <param name="user">The user to test.</param>
/// <param name="deviceId">The device id to test.</param>
/// <returns>Whether the user can access the device.</returns>
bool CanAccessDevice(User user, string deviceId);
Task UpdateDeviceOptions(string deviceId, string deviceName);
/// <summary>
/// Updates the options of a device.
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <param name="deviceName">The device name.</param>
/// <returns>A <see cref="Task"/> representing the update of the device options.</returns>
Task UpdateDeviceOptions(string deviceId, string? deviceName);
DeviceOptions GetDeviceOptions(string deviceId);
}
/// <summary>
/// Gets the options of a device.
/// </summary>
/// <param name="deviceId">The device id.</param>
/// <returns><see cref="DeviceOptions"/> of the device.</returns>
DeviceOptionsDto? GetDeviceOptions(string deviceId);
/// <summary>
/// Gets the dto for client capabilites.
/// </summary>
/// <param name="capabilities">The client capabilities.</param>
/// <returns><see cref="ClientCapabilitiesDto"/> of the device.</returns>
ClientCapabilitiesDto ToClientCapabilitiesDto(ClientCapabilities capabilities);
}

View File

@@ -1,6 +1,5 @@
using System;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
namespace MediaBrowser.Controller.Events.Authentication;
@@ -29,7 +28,7 @@ public class AuthenticationResultEventArgs : EventArgs
/// <summary>
/// Gets or sets the session information.
/// </summary>
public SessionInfo? SessionInfo { get; set; }
public SessionInfoDto? SessionInfo { get; set; }
/// <summary>
/// Gets or sets the server id.

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.ComponentModel;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound;
@@ -8,13 +9,13 @@ namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound;
/// <summary>
/// Sessions message.
/// </summary>
public class SessionsMessage : OutboundWebSocketMessage<IReadOnlyList<SessionInfo>>
public class SessionsMessage : OutboundWebSocketMessage<IReadOnlyList<SessionInfoDto>>
{
/// <summary>
/// Initializes a new instance of the <see cref="SessionsMessage"/> class.
/// </summary>
/// <param name="data">Session info.</param>
public SessionsMessage(IReadOnlyList<SessionInfo> data)
public SessionsMessage(IReadOnlyList<SessionInfoDto> data)
: base(data)
{
}

View File

@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Jellyfin.Data.Entities.Security;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Session;
using MediaBrowser.Model.SyncPlay;
@@ -292,6 +293,16 @@ namespace MediaBrowser.Controller.Session
/// <returns>SessionInfo.</returns>
SessionInfo GetSession(string deviceId, string client, string version);
/// <summary>
/// Gets all sessions available to a user.
/// </summary>
/// <param name="userId">The session identifier.</param>
/// <param name="deviceId">The device id.</param>
/// <param name="activeWithinSeconds">Active within session limit.</param>
/// <param name="controllableUserToCheck">Filter for sessions remote controllable for this user.</param>
/// <returns>IReadOnlyList{SessionInfoDto}.</returns>
IReadOnlyList<SessionInfoDto> GetSessions(Guid userId, string deviceId, int? activeWithinSeconds, Guid? controllableUserToCheck);
/// <summary>
/// Gets the session by authentication token.
/// </summary>

View File

@@ -1,7 +1,5 @@
#nullable disable
#pragma warning disable CS1591
using System;
using System.Collections.Generic;
using System.Linq;
@@ -27,28 +25,45 @@ namespace MediaBrowser.Controller.Session
private readonly ISessionManager _sessionManager;
private readonly ILogger _logger;
private readonly object _progressLock = new object();
private readonly object _progressLock = new();
private Timer _progressTimer;
private PlaybackProgressInfo _lastProgressInfo;
private bool _disposed = false;
private bool _disposed;
/// <summary>
/// Initializes a new instance of the <see cref="SessionInfo"/> class.
/// </summary>
/// <param name="sessionManager">Instance of <see cref="ISessionManager"/> interface.</param>
/// <param name="logger">Instance of <see cref="ILogger"/> interface.</param>
public SessionInfo(ISessionManager sessionManager, ILogger logger)
{
_sessionManager = sessionManager;
_logger = logger;
AdditionalUsers = Array.Empty<SessionUserInfo>();
AdditionalUsers = [];
PlayState = new PlayerStateInfo();
SessionControllers = Array.Empty<ISessionController>();
NowPlayingQueue = Array.Empty<QueueItem>();
NowPlayingQueueFullItems = Array.Empty<BaseItemDto>();
SessionControllers = [];
NowPlayingQueue = [];
NowPlayingQueueFullItems = [];
}
/// <summary>
/// Gets or sets the play state.
/// </summary>
/// <value>The play state.</value>
public PlayerStateInfo PlayState { get; set; }
public SessionUserInfo[] AdditionalUsers { get; set; }
/// <summary>
/// Gets or sets the additional users.
/// </summary>
/// <value>The additional users.</value>
public IReadOnlyList<SessionUserInfo> AdditionalUsers { get; set; }
/// <summary>
/// Gets or sets the client capabilities.
/// </summary>
/// <value>The client capabilities.</value>
public ClientCapabilities Capabilities { get; set; }
/// <summary>
@@ -67,7 +82,7 @@ namespace MediaBrowser.Controller.Session
{
if (Capabilities is null)
{
return Array.Empty<MediaType>();
return [];
}
return Capabilities.PlayableMediaTypes;
@@ -134,9 +149,17 @@ namespace MediaBrowser.Controller.Session
/// <value>The now playing item.</value>
public BaseItemDto NowPlayingItem { get; set; }
/// <summary>
/// Gets or sets the now playing queue full items.
/// </summary>
/// <value>The now playing queue full items.</value>
[JsonIgnore]
public BaseItem FullNowPlayingItem { get; set; }
/// <summary>
/// Gets or sets the now viewing item.
/// </summary>
/// <value>The now viewing item.</value>
public BaseItemDto NowViewingItem { get; set; }
/// <summary>
@@ -156,8 +179,12 @@ namespace MediaBrowser.Controller.Session
/// </summary>
/// <value>The session controller.</value>
[JsonIgnore]
public ISessionController[] SessionControllers { get; set; }
public IReadOnlyList<ISessionController> SessionControllers { get; set; }
/// <summary>
/// Gets or sets the transcoding info.
/// </summary>
/// <value>The transcoding info.</value>
public TranscodingInfo TranscodingInfo { get; set; }
/// <summary>
@@ -177,7 +204,7 @@ namespace MediaBrowser.Controller.Session
}
}
if (controllers.Length > 0)
if (controllers.Count > 0)
{
return false;
}
@@ -186,6 +213,10 @@ namespace MediaBrowser.Controller.Session
}
}
/// <summary>
/// Gets a value indicating whether the session supports media control.
/// </summary>
/// <value><c>true</c> if this session supports media control; otherwise, <c>false</c>.</value>
public bool SupportsMediaControl
{
get
@@ -208,6 +239,10 @@ namespace MediaBrowser.Controller.Session
}
}
/// <summary>
/// Gets a value indicating whether the session supports remote control.
/// </summary>
/// <value><c>true</c> if this session supports remote control; otherwise, <c>false</c>.</value>
public bool SupportsRemoteControl
{
get
@@ -230,16 +265,40 @@ namespace MediaBrowser.Controller.Session
}
}
/// <summary>
/// Gets or sets the now playing queue.
/// </summary>
/// <value>The now playing queue.</value>
public IReadOnlyList<QueueItem> NowPlayingQueue { get; set; }
/// <summary>
/// Gets or sets the now playing queue full items.
/// </summary>
/// <value>The now playing queue full items.</value>
public IReadOnlyList<BaseItemDto> NowPlayingQueueFullItems { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the session has a custom device name.
/// </summary>
/// <value><c>true</c> if this session has a custom device name; otherwise, <c>false</c>.</value>
public bool HasCustomDeviceName { get; set; }
/// <summary>
/// Gets or sets the playlist item id.
/// </summary>
/// <value>The splaylist item id.</value>
public string PlaylistItemId { get; set; }
/// <summary>
/// Gets or sets the server id.
/// </summary>
/// <value>The server id.</value>
public string ServerId { get; set; }
/// <summary>
/// Gets or sets the user primary image tag.
/// </summary>
/// <value>The user primary image tag.</value>
public string UserPrimaryImageTag { get; set; }
/// <summary>
@@ -247,8 +306,14 @@ namespace MediaBrowser.Controller.Session
/// </summary>
/// <value>The supported commands.</value>
public IReadOnlyList<GeneralCommandType> SupportedCommands
=> Capabilities is null ? Array.Empty<GeneralCommandType>() : Capabilities.SupportedCommands;
=> Capabilities is null ? [] : Capabilities.SupportedCommands;
/// <summary>
/// Ensures a controller of type exists.
/// </summary>
/// <typeparam name="T">Class to register.</typeparam>
/// <param name="factory">The factory.</param>
/// <returns>Tuple{ISessionController, bool}.</returns>
public Tuple<ISessionController, bool> EnsureController<T>(Func<SessionInfo, ISessionController> factory)
{
var controllers = SessionControllers.ToList();
@@ -261,18 +326,27 @@ namespace MediaBrowser.Controller.Session
}
var newController = factory(this);
_logger.LogDebug("Creating new {0}", newController.GetType().Name);
_logger.LogDebug("Creating new {Factory}", newController.GetType().Name);
controllers.Add(newController);
SessionControllers = controllers.ToArray();
SessionControllers = [.. controllers];
return new Tuple<ISessionController, bool>(newController, true);
}
/// <summary>
/// Adds a controller to the session.
/// </summary>
/// <param name="controller">The controller.</param>
public void AddController(ISessionController controller)
{
SessionControllers = [..SessionControllers, controller];
SessionControllers = [.. SessionControllers, controller];
}
/// <summary>
/// Gets a value indicating whether the session contains a user.
/// </summary>
/// <param name="userId">The user id to check.</param>
/// <returns><c>true</c> if this session contains the user; otherwise, <c>false</c>.</returns>
public bool ContainsUser(Guid userId)
{
if (UserId.Equals(userId))
@@ -291,6 +365,11 @@ namespace MediaBrowser.Controller.Session
return false;
}
/// <summary>
/// Starts automatic progressing.
/// </summary>
/// <param name="progressInfo">The playback progress info.</param>
/// <value>The supported commands.</value>
public void StartAutomaticProgress(PlaybackProgressInfo progressInfo)
{
if (_disposed)
@@ -359,6 +438,9 @@ namespace MediaBrowser.Controller.Session
}
}
/// <summary>
/// Stops automatic progressing.
/// </summary>
public void StopAutomaticProgress()
{
lock (_progressLock)
@@ -373,6 +455,10 @@ namespace MediaBrowser.Controller.Session
}
}
/// <summary>
/// Disposes the instance async.
/// </summary>
/// <returns>ValueTask.</returns>
public async ValueTask DisposeAsync()
{
_disposed = true;
@@ -380,7 +466,7 @@ namespace MediaBrowser.Controller.Session
StopAutomaticProgress();
var controllers = SessionControllers.ToList();
SessionControllers = Array.Empty<ISessionController>();
SessionControllers = [];
foreach (var controller in controllers)
{