Merge branch 'master' into userdb-efcore

# Conflicts:
#	Emby.Server.Implementations/Library/UserManager.cs
#	Jellyfin.Data/Jellyfin.Data.csproj
#	MediaBrowser.Api/UserService.cs
#	MediaBrowser.Controller/Library/IUserManager.cs
This commit is contained in:
Patrick Barron
2020-05-26 20:29:11 -04:00
86 changed files with 2894 additions and 455 deletions

View File

@@ -141,14 +141,6 @@ namespace MediaBrowser.Controller.Library
/// <returns>UserDto.</returns>
UserDto GetUserDto(User user, string remoteEndPoint = null);
/// <summary>
/// Gets the user public dto.
/// </summary>
/// <param name="user">The user.</param>\
/// <param name="remoteEndPoint">The remote end point.</param>
/// <returns>A public UserDto, aka a UserDto stripped of personal data.</returns>
PublicUserDto GetPublicUserDto(User user, string remoteEndPoint = null);
/// <summary>
/// Authenticates the user.
/// </summary>

View File

@@ -13,8 +13,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="3.1.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="3.1.4" />
</ItemGroup>
<ItemGroup>

View File

@@ -23,6 +23,12 @@ namespace MediaBrowser.Controller.Net
/// <value>The last activity date.</value>
DateTime LastActivityDate { get; }
/// <summary>
/// Gets or sets the date of last Keeplive received.
/// </summary>
/// <value>The date of last Keeplive received.</value>
DateTime LastKeepAliveDate { get; set; }
/// <summary>
/// Gets or sets the query string.
/// </summary>

View File

@@ -9,6 +9,7 @@ using MediaBrowser.Controller.Security;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Session;
using MediaBrowser.Model.SyncPlay;
namespace MediaBrowser.Controller.Session
{
@@ -140,6 +141,24 @@ namespace MediaBrowser.Controller.Session
/// <returns>Task.</returns>
Task SendPlayCommand(string controllingSessionId, string sessionId, PlayRequest command, CancellationToken cancellationToken);
/// <summary>
/// Sends the SyncPlayCommand.
/// </summary>
/// <param name="sessionId">The session id.</param>
/// <param name="command">The command.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task SendSyncPlayCommand(string sessionId, SendCommand command, CancellationToken cancellationToken);
/// <summary>
/// Sends the SyncPlayGroupUpdate.
/// </summary>
/// <param name="sessionId">The session id.</param>
/// <param name="command">The group update.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task SendSyncPlayGroupUpdate<T>(string sessionId, GroupUpdate<T> command, CancellationToken cancellationToken);
/// <summary>
/// Sends the browse command.
/// </summary>

View File

@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Session;
namespace MediaBrowser.Controller.SyncPlay
{
/// <summary>
/// Class GroupInfo.
/// </summary>
/// <remarks>
/// Class is not thread-safe, external locking is required when accessing methods.
/// </remarks>
public class GroupInfo
{
/// <summary>
/// Default ping value used for sessions.
/// </summary>
public long DefaulPing { get; } = 500;
/// <summary>
/// Gets or sets the group identifier.
/// </summary>
/// <value>The group identifier.</value>
public Guid GroupId { get; } = Guid.NewGuid();
/// <summary>
/// Gets or sets the playing item.
/// </summary>
/// <value>The playing item.</value>
public BaseItem PlayingItem { get; set; }
/// <summary>
/// Gets or sets whether playback is paused.
/// </summary>
/// <value>Playback is paused.</value>
public bool IsPaused { get; set; }
/// <summary>
/// Gets or sets the position ticks.
/// </summary>
/// <value>The position ticks.</value>
public long PositionTicks { get; set; }
/// <summary>
/// Gets or sets the last activity.
/// </summary>
/// <value>The last activity.</value>
public DateTime LastActivity { get; set; }
/// <summary>
/// Gets the participants.
/// </summary>
/// <value>The participants, or members of the group.</value>
public Dictionary<string, GroupMember> Participants { get; } =
new Dictionary<string, GroupMember>(StringComparer.OrdinalIgnoreCase);
/// <summary>
/// Checks if a session is in this group.
/// </summary>
/// <value><c>true</c> if the session is in this group; <c>false</c> otherwise.</value>
public bool ContainsSession(string sessionId)
{
return Participants.ContainsKey(sessionId);
}
/// <summary>
/// Adds the session to the group.
/// </summary>
/// <param name="session">The session.</param>
public void AddSession(SessionInfo session)
{
if (ContainsSession(session.Id.ToString()))
{
return;
}
var member = new GroupMember();
member.Session = session;
member.Ping = DefaulPing;
member.IsBuffering = false;
Participants[session.Id.ToString()] = member;
}
/// <summary>
/// Removes the session from the group.
/// </summary>
/// <param name="session">The session.</param>
public void RemoveSession(SessionInfo session)
{
if (!ContainsSession(session.Id.ToString()))
{
return;
}
Participants.Remove(session.Id.ToString(), out _);
}
/// <summary>
/// Updates the ping of a session.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="ping">The ping.</param>
public void UpdatePing(SessionInfo session, long ping)
{
if (!ContainsSession(session.Id.ToString()))
{
return;
}
Participants[session.Id.ToString()].Ping = ping;
}
/// <summary>
/// Gets the highest ping in the group.
/// </summary>
/// <value name="session">The highest ping in the group.</value>
public long GetHighestPing()
{
long max = Int64.MinValue;
foreach (var session in Participants.Values)
{
max = Math.Max(max, session.Ping);
}
return max;
}
/// <summary>
/// Sets the session's buffering state.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="isBuffering">The state.</param>
public void SetBuffering(SessionInfo session, bool isBuffering)
{
if (!ContainsSession(session.Id.ToString()))
{
return;
}
Participants[session.Id.ToString()].IsBuffering = isBuffering;
}
/// <summary>
/// Gets the group buffering state.
/// </summary>
/// <value><c>true</c> if there is a session buffering in the group; <c>false</c> otherwise.</value>
public bool IsBuffering()
{
foreach (var session in Participants.Values)
{
if (session.IsBuffering)
{
return true;
}
}
return false;
}
/// <summary>
/// Checks if the group is empty.
/// </summary>
/// <value><c>true</c> if the group is empty; <c>false</c> otherwise.</value>
public bool IsEmpty()
{
return Participants.Count == 0;
}
}
}

View File

@@ -0,0 +1,28 @@
using MediaBrowser.Controller.Session;
namespace MediaBrowser.Controller.SyncPlay
{
/// <summary>
/// Class GroupMember.
/// </summary>
public class GroupMember
{
/// <summary>
/// Gets or sets whether this member is buffering.
/// </summary>
/// <value><c>true</c> if member is buffering; <c>false</c> otherwise.</value>
public bool IsBuffering { get; set; }
/// <summary>
/// Gets or sets the session.
/// </summary>
/// <value>The session.</value>
public SessionInfo Session { get; set; }
/// <summary>
/// Gets or sets the ping.
/// </summary>
/// <value>The ping.</value>
public long Ping { get; set; }
}
}

View File

@@ -0,0 +1,67 @@
using System;
using System.Threading;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.SyncPlay;
namespace MediaBrowser.Controller.SyncPlay
{
/// <summary>
/// Interface ISyncPlayController.
/// </summary>
public interface ISyncPlayController
{
/// <summary>
/// Gets the group id.
/// </summary>
/// <value>The group id.</value>
Guid GetGroupId();
/// <summary>
/// Gets the playing item id.
/// </summary>
/// <value>The playing item id.</value>
Guid GetPlayingItemId();
/// <summary>
/// Checks if the group is empty.
/// </summary>
/// <value>If the group is empty.</value>
bool IsGroupEmpty();
/// <summary>
/// Initializes the group with the session's info.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void InitGroup(SessionInfo session, CancellationToken cancellationToken);
/// <summary>
/// Adds the session to the group.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="request">The request.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void SessionJoin(SessionInfo session, JoinGroupRequest request, CancellationToken cancellationToken);
/// <summary>
/// Removes the session from the group.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void SessionLeave(SessionInfo session, CancellationToken cancellationToken);
/// <summary>
/// Handles the requested action by the session.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="request">The requested action.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void HandleRequest(SessionInfo session, PlaybackRequest request, CancellationToken cancellationToken);
/// <summary>
/// Gets the info about the group for the clients.
/// </summary>
/// <value>The group info for the clients.</value>
GroupInfoView GetInfo();
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Threading;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.SyncPlay;
namespace MediaBrowser.Controller.SyncPlay
{
/// <summary>
/// Interface ISyncPlayManager.
/// </summary>
public interface ISyncPlayManager
{
/// <summary>
/// Creates a new group.
/// </summary>
/// <param name="session">The session that's creating the group.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void NewGroup(SessionInfo session, CancellationToken cancellationToken);
/// <summary>
/// Adds the session to a group.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="groupId">The group id.</param>
/// <param name="request">The request.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void JoinGroup(SessionInfo session, Guid groupId, JoinGroupRequest request, CancellationToken cancellationToken);
/// <summary>
/// Removes the session from a group.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void LeaveGroup(SessionInfo session, CancellationToken cancellationToken);
/// <summary>
/// Gets list of available groups for a session.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="filterItemId">The item id to filter by.</param>
/// <value>The list of available groups.</value>
List<GroupInfoView> ListGroups(SessionInfo session, Guid filterItemId);
/// <summary>
/// Handle a request by a session in a group.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="request">The request.</param>
/// <param name="cancellationToken">The cancellation token.</param>
void HandleRequest(SessionInfo session, PlaybackRequest request, CancellationToken cancellationToken);
/// <summary>
/// Maps a session to a group.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="group">The group.</param>
/// <exception cref="InvalidOperationException"></exception>
void AddSessionToGroup(SessionInfo session, ISyncPlayController group);
/// <summary>
/// Unmaps a session from a group.
/// </summary>
/// <param name="session">The session.</param>
/// <param name="group">The group.</param>
/// <exception cref="InvalidOperationException"></exception>
void RemoveSessionFromGroup(SessionInfo session, ISyncPlayController group);
}
}