support adding additional users to sessions
This commit is contained in:
parent
6da4231244
commit
135168b0e0
|
@ -172,6 +172,28 @@ namespace MediaBrowser.Api
|
||||||
public long? TimeoutMs { get; set; }
|
public long? TimeoutMs { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Route("/Sessions/{Id}/Users/{UserId}", "POST")]
|
||||||
|
[Api(("Adds an additional user to a session"))]
|
||||||
|
public class AddUserToSession : IReturnVoid
|
||||||
|
{
|
||||||
|
[ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "UserId", Description = "UserId Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||||
|
public Guid UserId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Route("/Sessions/{Id}/Users/{UserId}", "DELETE")]
|
||||||
|
[Api(("Removes an additional user from a session"))]
|
||||||
|
public class RemoveUserFromSession : IReturnVoid
|
||||||
|
{
|
||||||
|
[ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
|
||||||
|
[ApiMember(Name = "UserId", Description = "UserId Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||||
|
public Guid UserId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class SessionsService
|
/// Class SessionsService
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -217,7 +239,7 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
if (!user.Configuration.EnableRemoteControlOfOtherUsers)
|
if (!user.Configuration.EnableRemoteControlOfOtherUsers)
|
||||||
{
|
{
|
||||||
result = result.Where(i => i.User == null || i.User.Id == request.ControllableByUserId.Value);
|
result = result.Where(i => !i.UserId.HasValue || i.UserId.Value == request.ControllableByUserId.Value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,5 +325,15 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
Task.WaitAll(task);
|
Task.WaitAll(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Post(AddUserToSession request)
|
||||||
|
{
|
||||||
|
_sessionManager.AddAdditionalUser(request.Id, request.UserId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Delete(RemoveUserFromSession request)
|
||||||
|
{
|
||||||
|
_sessionManager.RemoveAdditionalUser(request.Id, request.UserId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,9 @@ namespace MediaBrowser.Controller.Entities.TV
|
||||||
|
|
||||||
public List<MediaUrl> RemoteTrailers { get; set; }
|
public List<MediaUrl> RemoteTrailers { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// airdate, dvd or absolute
|
||||||
|
/// </summary>
|
||||||
public string DisplayOrder { get; set; }
|
public string DisplayOrder { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using MediaBrowser.Controller.Entities;
|
||||||
using MediaBrowser.Controller.Entities;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MediaBrowser.Controller.Library
|
namespace MediaBrowser.Controller.Library
|
||||||
{
|
{
|
||||||
|
@ -8,10 +9,14 @@ namespace MediaBrowser.Controller.Library
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PlaybackProgressEventArgs : EventArgs
|
public class PlaybackProgressEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public User User { get; set; }
|
public List<User> Users { get; set; }
|
||||||
public long? PlaybackPositionTicks { get; set; }
|
public long? PlaybackPositionTicks { get; set; }
|
||||||
public BaseItem Item { get; set; }
|
public BaseItem Item { get; set; }
|
||||||
public UserItemData UserData { get; set; }
|
|
||||||
|
public PlaybackProgressEventArgs()
|
||||||
|
{
|
||||||
|
Users = new List<User>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PlaybackStopEventArgs : PlaybackProgressEventArgs
|
public class PlaybackStopEventArgs : PlaybackProgressEventArgs
|
||||||
|
|
|
@ -141,5 +141,19 @@ namespace MediaBrowser.Controller.Session
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
Task SendServerRestartNotification(CancellationToken cancellationToken);
|
Task SendServerRestartNotification(CancellationToken cancellationToken);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the additional user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sessionId">The session identifier.</param>
|
||||||
|
/// <param name="userId">The user identifier.</param>
|
||||||
|
void AddAdditionalUser(Guid sessionId, Guid userId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the additional user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sessionId">The session identifier.</param>
|
||||||
|
/// <param name="userId">The user identifier.</param>
|
||||||
|
void RemoveAdditionalUser(Guid sessionId, Guid userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using MediaBrowser.Controller.Entities;
|
using MediaBrowser.Controller.Entities;
|
||||||
|
using MediaBrowser.Model.Session;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -12,8 +13,12 @@ namespace MediaBrowser.Controller.Session
|
||||||
public SessionInfo()
|
public SessionInfo()
|
||||||
{
|
{
|
||||||
QueueableMediaTypes = new List<string>();
|
QueueableMediaTypes = new List<string>();
|
||||||
|
|
||||||
|
AdditionalUsersPresent = new List<SessionUserInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<SessionUserInfo> AdditionalUsersPresent { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the remote end point.
|
/// Gets or sets the remote end point.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -31,7 +36,7 @@ namespace MediaBrowser.Controller.Session
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The queueable media types.</value>
|
/// <value>The queueable media types.</value>
|
||||||
public List<string> QueueableMediaTypes { get; set; }
|
public List<string> QueueableMediaTypes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the id.
|
/// Gets or sets the id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -42,7 +47,13 @@ namespace MediaBrowser.Controller.Session
|
||||||
/// Gets or sets the user id.
|
/// Gets or sets the user id.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The user id.</value>
|
/// <value>The user id.</value>
|
||||||
public User User { get; set; }
|
public Guid? UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the username.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The username.</value>
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the type of the client.
|
/// Gets or sets the type of the client.
|
||||||
|
|
|
@ -392,6 +392,12 @@ namespace MediaBrowser.Model.Dto
|
||||||
/// <value>The album.</value>
|
/// <value>The album.</value>
|
||||||
public string Album { get; set; }
|
public string Album { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the type of the collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The type of the collection.</value>
|
||||||
|
public string CollectionType { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the display order.
|
/// Gets or sets the display order.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -43,6 +43,12 @@ namespace MediaBrowser.Model.Session
|
||||||
/// <value>The name of the user.</value>
|
/// <value>The name of the user.</value>
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the additional users present.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The additional users present.</value>
|
||||||
|
public List<SessionUserInfo> AdditionalUsersPresent { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the application version.
|
/// Gets or sets the application version.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -128,5 +134,27 @@ namespace MediaBrowser.Model.Session
|
||||||
public bool SupportsRemoteControl { get; set; }
|
public bool SupportsRemoteControl { get; set; }
|
||||||
|
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
public SessionInfoDto()
|
||||||
|
{
|
||||||
|
AdditionalUsersPresent = new List<SessionUserInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Class SessionUserInfo.
|
||||||
|
/// </summary>
|
||||||
|
public class SessionUserInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the user identifier.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The user identifier.</value>
|
||||||
|
public string UserId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the name of the user.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The name of the user.</value>
|
||||||
|
public string UserName { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,7 +244,8 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
ApplicationVersion = session.ApplicationVersion,
|
ApplicationVersion = session.ApplicationVersion,
|
||||||
CanSeek = session.CanSeek,
|
CanSeek = session.CanSeek,
|
||||||
QueueableMediaTypes = session.QueueableMediaTypes,
|
QueueableMediaTypes = session.QueueableMediaTypes,
|
||||||
RemoteEndPoint = session.RemoteEndPoint
|
RemoteEndPoint = session.RemoteEndPoint,
|
||||||
|
AdditionalUsersPresent = session.AdditionalUsersPresent
|
||||||
};
|
};
|
||||||
|
|
||||||
if (session.NowPlayingItem != null)
|
if (session.NowPlayingItem != null)
|
||||||
|
@ -252,11 +253,11 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
dto.NowPlayingItem = GetBaseItemInfo(session.NowPlayingItem);
|
dto.NowPlayingItem = GetBaseItemInfo(session.NowPlayingItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session.User != null)
|
if (session.UserId.HasValue)
|
||||||
{
|
{
|
||||||
dto.UserId = session.User.Id.ToString("N");
|
dto.UserId = session.UserId.Value.ToString("N");
|
||||||
dto.UserName = session.User.Name;
|
|
||||||
}
|
}
|
||||||
|
dto.UserName = session.UserName;
|
||||||
|
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
@ -769,6 +770,12 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||||
{
|
{
|
||||||
dto.DisplayOrder = hasDisplayOrder.DisplayOrder;
|
dto.DisplayOrder = hasDisplayOrder.DisplayOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var collectionFolder = item as CollectionFolder;
|
||||||
|
if (collectionFolder != null)
|
||||||
|
{
|
||||||
|
dto.CollectionType = collectionFolder.CollectionType;
|
||||||
|
}
|
||||||
|
|
||||||
if (fields.Contains(ItemFields.RemoteTrailers))
|
if (fields.Contains(ItemFields.RemoteTrailers))
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,7 +190,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
var id = user.Id;
|
var id = user.Id;
|
||||||
var userSessions = _sessionManager.Sessions
|
var userSessions = _sessionManager.Sessions
|
||||||
.Where(u => u.User != null && u.User.Id == id && u.SessionController != null && u.IsActive)
|
.Where(u => u.UserId.HasValue && u.UserId.Value == id && u.SessionController != null && u.IsActive)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (userSessions.Count > 0)
|
if (userSessions.Count > 0)
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||||
{
|
{
|
||||||
var userId = pair.Key;
|
var userId = pair.Key;
|
||||||
var userSessions = _sessionManager.Sessions
|
var userSessions = _sessionManager.Sessions
|
||||||
.Where(u => u.User != null && u.User.Id == userId && u.SessionController != null && u.IsActive)
|
.Where(u => u.UserId.HasValue && u.UserId.Value == userId && u.SessionController != null && u.IsActive)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (userSessions.Count > 0)
|
if (userSessions.Count > 0)
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
private readonly ILogger _logger;
|
private readonly ILogger _logger;
|
||||||
|
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
private readonly IUserManager _userManager;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the configuration manager.
|
/// Gets or sets the configuration manager.
|
||||||
|
@ -75,13 +76,14 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
/// <param name="logger">The logger.</param>
|
/// <param name="logger">The logger.</param>
|
||||||
/// <param name="userRepository">The user repository.</param>
|
/// <param name="userRepository">The user repository.</param>
|
||||||
/// <param name="libraryManager">The library manager.</param>
|
/// <param name="libraryManager">The library manager.</param>
|
||||||
public SessionManager(IUserDataManager userDataRepository, IServerConfigurationManager configurationManager, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager)
|
public SessionManager(IUserDataManager userDataRepository, IServerConfigurationManager configurationManager, ILogger logger, IUserRepository userRepository, ILibraryManager libraryManager, IUserManager userManager)
|
||||||
{
|
{
|
||||||
_userDataRepository = userDataRepository;
|
_userDataRepository = userDataRepository;
|
||||||
_configurationManager = configurationManager;
|
_configurationManager = configurationManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -140,7 +142,10 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
|
|
||||||
var activityDate = DateTime.UtcNow;
|
var activityDate = DateTime.UtcNow;
|
||||||
|
|
||||||
var session = GetSessionInfo(clientType, appVersion, deviceId, deviceName, remoteEndPoint, user);
|
var userId = user == null ? (Guid?)null : user.Id;
|
||||||
|
var username = user == null ? null : user.Name;
|
||||||
|
|
||||||
|
var session = GetSessionInfo(clientType, appVersion, deviceId, deviceName, remoteEndPoint, userId, username);
|
||||||
|
|
||||||
session.LastActivityDate = activityDate;
|
session.LastActivityDate = activityDate;
|
||||||
|
|
||||||
|
@ -209,9 +214,10 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
/// <param name="deviceId">The device id.</param>
|
/// <param name="deviceId">The device id.</param>
|
||||||
/// <param name="deviceName">Name of the device.</param>
|
/// <param name="deviceName">Name of the device.</param>
|
||||||
/// <param name="remoteEndPoint">The remote end point.</param>
|
/// <param name="remoteEndPoint">The remote end point.</param>
|
||||||
/// <param name="user">The user.</param>
|
/// <param name="userId">The user identifier.</param>
|
||||||
|
/// <param name="username">The username.</param>
|
||||||
/// <returns>SessionInfo.</returns>
|
/// <returns>SessionInfo.</returns>
|
||||||
private SessionInfo GetSessionInfo(string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint, User user)
|
private SessionInfo GetSessionInfo(string clientType, string appVersion, string deviceId, string deviceName, string remoteEndPoint, Guid? userId, string username)
|
||||||
{
|
{
|
||||||
var key = clientType + deviceId + appVersion;
|
var key = clientType + deviceId + appVersion;
|
||||||
|
|
||||||
|
@ -224,9 +230,15 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
});
|
});
|
||||||
|
|
||||||
connection.DeviceName = deviceName;
|
connection.DeviceName = deviceName;
|
||||||
connection.User = user;
|
connection.UserId = userId;
|
||||||
|
connection.UserName = username;
|
||||||
connection.RemoteEndPoint = remoteEndPoint;
|
connection.RemoteEndPoint = remoteEndPoint;
|
||||||
|
|
||||||
|
if (!userId.HasValue)
|
||||||
|
{
|
||||||
|
connection.AdditionalUsersPresent.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (connection.SessionController == null)
|
if (connection.SessionController == null)
|
||||||
{
|
{
|
||||||
connection.SessionController = _sessionFactories
|
connection.SessionController = _sessionFactories
|
||||||
|
@ -237,6 +249,31 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<User> GetUsers(SessionInfo session)
|
||||||
|
{
|
||||||
|
var users = new List<User>();
|
||||||
|
|
||||||
|
if (session.UserId.HasValue)
|
||||||
|
{
|
||||||
|
var user = _userManager.GetUserById(session.UserId.Value);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("User not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
users.Add(user);
|
||||||
|
|
||||||
|
var additionalUsers = session.AdditionalUsersPresent
|
||||||
|
.Select(i => _userManager.GetUserById(new Guid(i.UserId)))
|
||||||
|
.Where(i => i != null);
|
||||||
|
|
||||||
|
users.AddRange(additionalUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
return users;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to report that playback has started for an item
|
/// Used to report that playback has started for an item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -265,9 +302,33 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
|
|
||||||
var key = item.GetUserDataKey();
|
var key = item.GetUserDataKey();
|
||||||
|
|
||||||
var user = session.User;
|
var users = GetUsers(session);
|
||||||
|
|
||||||
var data = _userDataRepository.GetUserData(user.Id, key);
|
foreach (var user in users)
|
||||||
|
{
|
||||||
|
await OnPlaybackStart(user.Id, key, item).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nothing to save here
|
||||||
|
// Fire events to inform plugins
|
||||||
|
EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
|
||||||
|
{
|
||||||
|
Item = item,
|
||||||
|
Users = users
|
||||||
|
|
||||||
|
}, _logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when [playback start].
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId">The user identifier.</param>
|
||||||
|
/// <param name="userDataKey">The user data key.</param>
|
||||||
|
/// <param name="item">The item.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
private async Task OnPlaybackStart(Guid userId, string userDataKey, IHasUserData item)
|
||||||
|
{
|
||||||
|
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
||||||
|
|
||||||
data.PlayCount++;
|
data.PlayCount++;
|
||||||
data.LastPlayedDate = DateTime.UtcNow;
|
data.LastPlayedDate = DateTime.UtcNow;
|
||||||
|
@ -277,17 +338,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
data.Played = true;
|
data.Played = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false);
|
await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
// Nothing to save here
|
|
||||||
// Fire events to inform plugins
|
|
||||||
EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
|
|
||||||
{
|
|
||||||
Item = item,
|
|
||||||
User = user,
|
|
||||||
UserData = data
|
|
||||||
|
|
||||||
}, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -315,27 +366,34 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
|
|
||||||
var key = info.Item.GetUserDataKey();
|
var key = info.Item.GetUserDataKey();
|
||||||
|
|
||||||
var user = session.User;
|
var users = GetUsers(session);
|
||||||
|
|
||||||
var data = _userDataRepository.GetUserData(user.Id, key);
|
foreach (var user in users)
|
||||||
|
|
||||||
if (info.PositionTicks.HasValue)
|
|
||||||
{
|
{
|
||||||
UpdatePlayState(info.Item, data, info.PositionTicks.Value);
|
await OnPlaybackProgress(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
|
||||||
|
|
||||||
await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
|
EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
|
||||||
{
|
{
|
||||||
Item = info.Item,
|
Item = info.Item,
|
||||||
User = user,
|
Users = users,
|
||||||
PlaybackPositionTicks = info.PositionTicks,
|
PlaybackPositionTicks = info.PositionTicks
|
||||||
UserData = data
|
|
||||||
|
|
||||||
}, _logger);
|
}, _logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task OnPlaybackProgress(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
|
||||||
|
{
|
||||||
|
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
||||||
|
|
||||||
|
if (positionTicks.HasValue)
|
||||||
|
{
|
||||||
|
UpdatePlayState(item, data, positionTicks.Value);
|
||||||
|
|
||||||
|
await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to report that playback has ended for an item
|
/// Used to report that playback has ended for an item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -371,14 +429,32 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
|
|
||||||
var key = info.Item.GetUserDataKey();
|
var key = info.Item.GetUserDataKey();
|
||||||
|
|
||||||
var user = session.User;
|
var users = GetUsers(session);
|
||||||
|
|
||||||
var data = _userDataRepository.GetUserData(user.Id, key);
|
var playedToCompletion = false;
|
||||||
|
foreach (var user in users)
|
||||||
|
{
|
||||||
|
playedToCompletion = await OnPlaybackStopped(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
|
||||||
|
{
|
||||||
|
Item = info.Item,
|
||||||
|
Users = users,
|
||||||
|
PlaybackPositionTicks = info.PositionTicks,
|
||||||
|
PlayedToCompletion = playedToCompletion
|
||||||
|
|
||||||
|
}, _logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks)
|
||||||
|
{
|
||||||
|
var data = _userDataRepository.GetUserData(userId, userDataKey);
|
||||||
bool playedToCompletion;
|
bool playedToCompletion;
|
||||||
|
|
||||||
if (info.PositionTicks.HasValue)
|
if (positionTicks.HasValue)
|
||||||
{
|
{
|
||||||
playedToCompletion = UpdatePlayState(info.Item, data, info.PositionTicks.Value);
|
playedToCompletion = UpdatePlayState(item, data, positionTicks.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -389,19 +465,11 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
playedToCompletion = true;
|
playedToCompletion = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);
|
await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false);
|
||||||
|
|
||||||
EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs
|
return playedToCompletion;
|
||||||
{
|
|
||||||
Item = info.Item,
|
|
||||||
User = user,
|
|
||||||
PlaybackPositionTicks = info.PositionTicks,
|
|
||||||
UserData = data,
|
|
||||||
PlayedToCompletion = playedToCompletion
|
|
||||||
|
|
||||||
}, _logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates playstate position for an item but does not save
|
/// Updates playstate position for an item but does not save
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -462,12 +530,12 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the session for remote control.
|
/// Gets the session.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sessionId">The session id.</param>
|
/// <param name="sessionId">The session identifier.</param>
|
||||||
/// <returns>SessionInfo.</returns>
|
/// <returns>SessionInfo.</returns>
|
||||||
/// <exception cref="ResourceNotFoundException"></exception>
|
/// <exception cref="ResourceNotFoundException"></exception>
|
||||||
private SessionInfo GetSessionForRemoteControl(Guid sessionId)
|
private SessionInfo GetSession(Guid sessionId)
|
||||||
{
|
{
|
||||||
var session = Sessions.First(i => i.Id.Equals(sessionId));
|
var session = Sessions.First(i => i.Id.Equals(sessionId));
|
||||||
|
|
||||||
|
@ -476,6 +544,19 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
throw new ResourceNotFoundException(string.Format("Session {0} not found.", sessionId));
|
throw new ResourceNotFoundException(string.Format("Session {0} not found.", sessionId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the session for remote control.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sessionId">The session id.</param>
|
||||||
|
/// <returns>SessionInfo.</returns>
|
||||||
|
/// <exception cref="ResourceNotFoundException"></exception>
|
||||||
|
private SessionInfo GetSessionForRemoteControl(Guid sessionId)
|
||||||
|
{
|
||||||
|
var session = GetSession(sessionId);
|
||||||
|
|
||||||
if (!session.SupportsRemoteControl)
|
if (!session.SupportsRemoteControl)
|
||||||
{
|
{
|
||||||
throw new ArgumentException(string.Format("Session {0} does not support remote control.", session.Id));
|
throw new ArgumentException(string.Format("Session {0} does not support remote control.", session.Id));
|
||||||
|
@ -595,7 +676,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
_logger.ErrorException("Error in SendRestartRequiredNotification.", ex);
|
_logger.ErrorException("Error in SendRestartRequiredNotification.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
}));
|
}, cancellationToken));
|
||||||
|
|
||||||
return Task.WhenAll(tasks);
|
return Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
@ -649,5 +730,68 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
|
|
||||||
return Task.WhenAll(tasks);
|
return Task.WhenAll(tasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the additional user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sessionId">The session identifier.</param>
|
||||||
|
/// <param name="userId">The user identifier.</param>
|
||||||
|
/// <exception cref="System.UnauthorizedAccessException">Cannot modify additional users without authenticating first.</exception>
|
||||||
|
/// <exception cref="System.ArgumentException">The requested user is already the primary user of the session.</exception>
|
||||||
|
public void AddAdditionalUser(Guid sessionId, Guid userId)
|
||||||
|
{
|
||||||
|
var session = GetSession(sessionId);
|
||||||
|
|
||||||
|
if (!session.UserId.HasValue)
|
||||||
|
{
|
||||||
|
throw new UnauthorizedAccessException("Cannot modify additional users without authenticating first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session.UserId.Value == userId)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The requested user is already the primary user of the session.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session.AdditionalUsersPresent.All(i => new Guid(i.UserId) != userId))
|
||||||
|
{
|
||||||
|
var user = _userManager.GetUserById(userId);
|
||||||
|
|
||||||
|
session.AdditionalUsersPresent.Add(new SessionUserInfo
|
||||||
|
{
|
||||||
|
UserId = userId.ToString("N"),
|
||||||
|
UserName = user.Name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the additional user.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sessionId">The session identifier.</param>
|
||||||
|
/// <param name="userId">The user identifier.</param>
|
||||||
|
/// <exception cref="System.UnauthorizedAccessException">Cannot modify additional users without authenticating first.</exception>
|
||||||
|
/// <exception cref="System.ArgumentException">The requested user is already the primary user of the session.</exception>
|
||||||
|
public void RemoveAdditionalUser(Guid sessionId, Guid userId)
|
||||||
|
{
|
||||||
|
var session = GetSession(sessionId);
|
||||||
|
|
||||||
|
if (!session.UserId.HasValue)
|
||||||
|
{
|
||||||
|
throw new UnauthorizedAccessException("Cannot modify additional users without authenticating first.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session.UserId.Value == userId)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The requested user is already the primary user of the session.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = session.AdditionalUsersPresent.FirstOrDefault(i => new Guid(i.UserId) == userId);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
session.AdditionalUsersPresent.Remove(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -191,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
|
|
||||||
var session = GetSessionFromMessage(message);
|
var session = GetSessionFromMessage(message);
|
||||||
|
|
||||||
if (session != null && session.User != null)
|
if (session != null && session.UserId.HasValue)
|
||||||
{
|
{
|
||||||
var vals = message.Data.Split('|');
|
var vals = message.Data.Split('|');
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
{
|
{
|
||||||
var session = GetSessionFromMessage(message);
|
var session = GetSessionFromMessage(message);
|
||||||
|
|
||||||
if (session != null && session.User != null)
|
if (session != null && session.UserId.HasValue)
|
||||||
{
|
{
|
||||||
var vals = message.Data.Split('|');
|
var vals = message.Data.Split('|');
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||||
|
|
||||||
var session = GetSessionFromMessage(message);
|
var session = GetSessionFromMessage(message);
|
||||||
|
|
||||||
if (session != null && session.User != null)
|
if (session != null && session.UserId.HasValue)
|
||||||
{
|
{
|
||||||
var vals = message.Data.Split('|');
|
var vals = message.Data.Split('|');
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ namespace MediaBrowser.ServerApplication
|
||||||
|
|
||||||
RegisterSingleInstance<ILibrarySearchEngine>(() => new LuceneSearchEngine(ApplicationPaths, LogManager, LibraryManager));
|
RegisterSingleInstance<ILibrarySearchEngine>(() => new LuceneSearchEngine(ApplicationPaths, LogManager, LibraryManager));
|
||||||
|
|
||||||
SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager);
|
SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager, UserManager);
|
||||||
RegisterSingleInstance(SessionManager);
|
RegisterSingleInstance(SessionManager);
|
||||||
|
|
||||||
HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", "mediabrowser", "dashboard/index.html");
|
HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", "mediabrowser", "dashboard/index.html");
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
window.MediaBrowser = {};
|
window.MediaBrowser = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, window) {
|
MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, window, FileReader) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new api client instance
|
* Creates a new api client instance
|
||||||
|
@ -3982,7 +3982,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}(jQuery, navigator, window.JSON, window.WebSocket, setTimeout, window);
|
}(jQuery, navigator, window.JSON, window.WebSocket, setTimeout, window, window.FileReader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a friendly way to create an api client instance using information from the browser's current url
|
* Provides a friendly way to create an api client instance using information from the browser's current url
|
||||||
|
@ -4208,7 +4208,7 @@ MediaBrowser.SHA1 = function (msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matched.platform) {
|
if (matched.platform) {
|
||||||
browser[matched.platform] = true
|
browser[matched.platform] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chrome is Webkit, but Webkit is also Safari.
|
// Chrome is Webkit, but Webkit is also Safari.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.217" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.218" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Reference in New Issue
Block a user