From 135168b0e0640211aee5cda9285cffb184385e83 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 3 Jan 2014 21:35:41 -0500 Subject: [PATCH] support adding additional users to sessions --- MediaBrowser.Api/SessionsService.cs | 34 ++- MediaBrowser.Controller/Entities/TV/Series.cs | 3 + .../Library/PlaybackProgressEventArgs.cs | 13 +- .../Session/ISessionManager.cs | 14 ++ .../Session/SessionInfo.cs | 15 +- MediaBrowser.Model/Dto/BaseItemDto.cs | 6 + MediaBrowser.Model/Session/SessionInfoDto.cs | 28 +++ .../Dto/DtoService.cs | 15 +- .../EntryPoints/LibraryChangedNotifier.cs | 2 +- .../EntryPoints/UserDataChangeNotifier.cs | 2 +- .../Session/SessionManager.cs | 236 ++++++++++++++---- .../Session/SessionWebSocketListener.cs | 6 +- .../ApplicationHost.cs | 2 +- MediaBrowser.WebDashboard/ApiClient.js | 6 +- MediaBrowser.WebDashboard/packages.config | 2 +- 15 files changed, 317 insertions(+), 67 deletions(-) diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs index 2a979888b7..0e95239e27 100644 --- a/MediaBrowser.Api/SessionsService.cs +++ b/MediaBrowser.Api/SessionsService.cs @@ -172,6 +172,28 @@ namespace MediaBrowser.Api 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; } + } + /// /// Class SessionsService /// @@ -217,7 +239,7 @@ namespace MediaBrowser.Api 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); } + + public void Post(AddUserToSession request) + { + _sessionManager.AddAdditionalUser(request.Id, request.UserId); + } + + public void Delete(RemoveUserFromSession request) + { + _sessionManager.RemoveAdditionalUser(request.Id, request.UserId); + } } } diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs index 135547a37d..552a517de5 100644 --- a/MediaBrowser.Controller/Entities/TV/Series.cs +++ b/MediaBrowser.Controller/Entities/TV/Series.cs @@ -45,6 +45,9 @@ namespace MediaBrowser.Controller.Entities.TV public List RemoteTrailers { get; set; } + /// + /// airdate, dvd or absolute + /// public string DisplayOrder { get; set; } /// diff --git a/MediaBrowser.Controller/Library/PlaybackProgressEventArgs.cs b/MediaBrowser.Controller/Library/PlaybackProgressEventArgs.cs index ec22193959..2ec3d308e3 100644 --- a/MediaBrowser.Controller/Library/PlaybackProgressEventArgs.cs +++ b/MediaBrowser.Controller/Library/PlaybackProgressEventArgs.cs @@ -1,5 +1,6 @@ -using System; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; +using System; +using System.Collections.Generic; namespace MediaBrowser.Controller.Library { @@ -8,10 +9,14 @@ namespace MediaBrowser.Controller.Library /// public class PlaybackProgressEventArgs : EventArgs { - public User User { get; set; } + public List Users { get; set; } public long? PlaybackPositionTicks { get; set; } public BaseItem Item { get; set; } - public UserItemData UserData { get; set; } + + public PlaybackProgressEventArgs() + { + Users = new List(); + } } public class PlaybackStopEventArgs : PlaybackProgressEventArgs diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index e0163a3e11..08797eecdc 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -141,5 +141,19 @@ namespace MediaBrowser.Controller.Session /// The cancellation token. /// Task. Task SendServerRestartNotification(CancellationToken cancellationToken); + + /// + /// Adds the additional user. + /// + /// The session identifier. + /// The user identifier. + void AddAdditionalUser(Guid sessionId, Guid userId); + + /// + /// Removes the additional user. + /// + /// The session identifier. + /// The user identifier. + void RemoveAdditionalUser(Guid sessionId, Guid userId); } } \ No newline at end of file diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 82e9328ac3..ce07f5dc47 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -1,4 +1,5 @@ using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Session; using System; using System.Collections.Generic; @@ -12,8 +13,12 @@ namespace MediaBrowser.Controller.Session public SessionInfo() { QueueableMediaTypes = new List(); + + AdditionalUsersPresent = new List(); } + public List AdditionalUsersPresent { get; set; } + /// /// Gets or sets the remote end point. /// @@ -31,7 +36,7 @@ namespace MediaBrowser.Controller.Session /// /// The queueable media types. public List QueueableMediaTypes { get; set; } - + /// /// Gets or sets the id. /// @@ -42,7 +47,13 @@ namespace MediaBrowser.Controller.Session /// Gets or sets the user id. /// /// The user id. - public User User { get; set; } + public Guid? UserId { get; set; } + + /// + /// Gets or sets the username. + /// + /// The username. + public string UserName { get; set; } /// /// Gets or sets the type of the client. diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs index 3bd4d52eec..665e36b88a 100644 --- a/MediaBrowser.Model/Dto/BaseItemDto.cs +++ b/MediaBrowser.Model/Dto/BaseItemDto.cs @@ -392,6 +392,12 @@ namespace MediaBrowser.Model.Dto /// The album. public string Album { get; set; } + /// + /// Gets or sets the type of the collection. + /// + /// The type of the collection. + public string CollectionType { get; set; } + /// /// Gets or sets the display order. /// diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs index 80f6ea2c00..f3980e2e4c 100644 --- a/MediaBrowser.Model/Session/SessionInfoDto.cs +++ b/MediaBrowser.Model/Session/SessionInfoDto.cs @@ -43,6 +43,12 @@ namespace MediaBrowser.Model.Session /// The name of the user. public string UserName { get; set; } + /// + /// Gets or sets the additional users present. + /// + /// The additional users present. + public List AdditionalUsersPresent { get; set; } + /// /// Gets or sets the application version. /// @@ -128,5 +134,27 @@ namespace MediaBrowser.Model.Session public bool SupportsRemoteControl { get; set; } public event PropertyChangedEventHandler PropertyChanged; + + public SessionInfoDto() + { + AdditionalUsersPresent = new List(); + } + } + + /// + /// Class SessionUserInfo. + /// + public class SessionUserInfo + { + /// + /// Gets or sets the user identifier. + /// + /// The user identifier. + public string UserId { get; set; } + /// + /// Gets or sets the name of the user. + /// + /// The name of the user. + public string UserName { get; set; } } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 4f97a6506d..c6c23ac2e5 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -244,7 +244,8 @@ namespace MediaBrowser.Server.Implementations.Dto ApplicationVersion = session.ApplicationVersion, CanSeek = session.CanSeek, QueueableMediaTypes = session.QueueableMediaTypes, - RemoteEndPoint = session.RemoteEndPoint + RemoteEndPoint = session.RemoteEndPoint, + AdditionalUsersPresent = session.AdditionalUsersPresent }; if (session.NowPlayingItem != null) @@ -252,11 +253,11 @@ namespace MediaBrowser.Server.Implementations.Dto dto.NowPlayingItem = GetBaseItemInfo(session.NowPlayingItem); } - if (session.User != null) + if (session.UserId.HasValue) { - dto.UserId = session.User.Id.ToString("N"); - dto.UserName = session.User.Name; + dto.UserId = session.UserId.Value.ToString("N"); } + dto.UserName = session.UserName; return dto; } @@ -769,6 +770,12 @@ namespace MediaBrowser.Server.Implementations.Dto { dto.DisplayOrder = hasDisplayOrder.DisplayOrder; } + + var collectionFolder = item as CollectionFolder; + if (collectionFolder != null) + { + dto.CollectionType = collectionFolder.CollectionType; + } if (fields.Contains(ItemFields.RemoteTrailers)) { diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs index 303109a65f..bbcc145246 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -190,7 +190,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints { var id = user.Id; 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(); if (userSessions.Count > 0) diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs index c495e424b3..d7186aa211 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -94,7 +94,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints { var userId = pair.Key; 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(); if (userSessions.Count > 0) diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs index 37b695776f..7a253b89b6 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs @@ -39,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Session private readonly ILogger _logger; private readonly ILibraryManager _libraryManager; + private readonly IUserManager _userManager; /// /// Gets or sets the configuration manager. @@ -75,13 +76,14 @@ namespace MediaBrowser.Server.Implementations.Session /// The logger. /// The user repository. /// The library manager. - 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; _configurationManager = configurationManager; _logger = logger; _userRepository = userRepository; _libraryManager = libraryManager; + _userManager = userManager; } /// @@ -140,7 +142,10 @@ namespace MediaBrowser.Server.Implementations.Session 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; @@ -209,9 +214,10 @@ namespace MediaBrowser.Server.Implementations.Session /// The device id. /// Name of the device. /// The remote end point. - /// The user. + /// The user identifier. + /// The username. /// SessionInfo. - 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; @@ -224,9 +230,15 @@ namespace MediaBrowser.Server.Implementations.Session }); connection.DeviceName = deviceName; - connection.User = user; + connection.UserId = userId; + connection.UserName = username; connection.RemoteEndPoint = remoteEndPoint; + if (!userId.HasValue) + { + connection.AdditionalUsersPresent.Clear(); + } + if (connection.SessionController == null) { connection.SessionController = _sessionFactories @@ -237,6 +249,31 @@ namespace MediaBrowser.Server.Implementations.Session return connection; } + private List GetUsers(SessionInfo session) + { + var users = new List(); + + 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; + } + /// /// Used to report that playback has started for an item /// @@ -265,31 +302,45 @@ namespace MediaBrowser.Server.Implementations.Session var key = item.GetUserDataKey(); - var user = session.User; - - var data = _userDataRepository.GetUserData(user.Id, key); - - data.PlayCount++; - data.LastPlayedDate = DateTime.UtcNow; + var users = GetUsers(session); - if (!(item is Video)) + foreach (var user in users) { - data.Played = true; + await OnPlaybackStart(user.Id, key, item).ConfigureAwait(false); } - await _userDataRepository.SaveUserData(user.Id, info.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 + Users = users }, _logger); } + /// + /// Called when [playback start]. + /// + /// The user identifier. + /// The user data key. + /// The item. + /// Task. + private async Task OnPlaybackStart(Guid userId, string userDataKey, IHasUserData item) + { + var data = _userDataRepository.GetUserData(userId, userDataKey); + + data.PlayCount++; + data.LastPlayedDate = DateTime.UtcNow; + + if (!(item is Video)) + { + data.Played = true; + } + + await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackStart, CancellationToken.None).ConfigureAwait(false); + } + /// /// Used to report playback progress for an item /// @@ -315,27 +366,34 @@ namespace MediaBrowser.Server.Implementations.Session var key = info.Item.GetUserDataKey(); - var user = session.User; + var users = GetUsers(session); - var data = _userDataRepository.GetUserData(user.Id, key); - - if (info.PositionTicks.HasValue) + foreach (var user in users) { - UpdatePlayState(info.Item, data, info.PositionTicks.Value); - - await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackProgress, CancellationToken.None).ConfigureAwait(false); + await OnPlaybackProgress(user.Id, key, info.Item, info.PositionTicks).ConfigureAwait(false); } EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs { Item = info.Item, - User = user, - PlaybackPositionTicks = info.PositionTicks, - UserData = data + Users = users, + PlaybackPositionTicks = info.PositionTicks }, _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); + } + } + /// /// Used to report that playback has ended for an item /// @@ -371,14 +429,32 @@ namespace MediaBrowser.Server.Implementations.Session var key = info.Item.GetUserDataKey(); - var user = session.User; + var users = GetUsers(session); + + 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); + } - var data = _userDataRepository.GetUserData(user.Id, key); + private async Task OnPlaybackStopped(Guid userId, string userDataKey, BaseItem item, long? positionTicks) + { + var data = _userDataRepository.GetUserData(userId, userDataKey); bool playedToCompletion; - if (info.PositionTicks.HasValue) + if (positionTicks.HasValue) { - playedToCompletion = UpdatePlayState(info.Item, data, info.PositionTicks.Value); + playedToCompletion = UpdatePlayState(item, data, positionTicks.Value); } else { @@ -389,19 +465,11 @@ namespace MediaBrowser.Server.Implementations.Session playedToCompletion = true; } - await _userDataRepository.SaveUserData(user.Id, info.Item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false); - - EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackStopEventArgs - { - Item = info.Item, - User = user, - PlaybackPositionTicks = info.PositionTicks, - UserData = data, - PlayedToCompletion = playedToCompletion + await _userDataRepository.SaveUserData(userId, item, data, UserDataSaveReason.PlaybackFinished, CancellationToken.None).ConfigureAwait(false); - }, _logger); + return playedToCompletion; } - + /// /// Updates playstate position for an item but does not save /// @@ -462,12 +530,12 @@ namespace MediaBrowser.Server.Implementations.Session } /// - /// Gets the session for remote control. + /// Gets the session. /// - /// The session id. + /// The session identifier. /// SessionInfo. /// - private SessionInfo GetSessionForRemoteControl(Guid sessionId) + private SessionInfo GetSession(Guid 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)); } + return session; + } + + /// + /// Gets the session for remote control. + /// + /// The session id. + /// SessionInfo. + /// + private SessionInfo GetSessionForRemoteControl(Guid sessionId) + { + var session = GetSession(sessionId); + if (!session.SupportsRemoteControl) { 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); } - })); + }, cancellationToken)); return Task.WhenAll(tasks); } @@ -649,5 +730,68 @@ namespace MediaBrowser.Server.Implementations.Session return Task.WhenAll(tasks); } + + + /// + /// Adds the additional user. + /// + /// The session identifier. + /// The user identifier. + /// Cannot modify additional users without authenticating first. + /// The requested user is already the primary user of the session. + 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 + }); + } + } + + /// + /// Removes the additional user. + /// + /// The session identifier. + /// The user identifier. + /// Cannot modify additional users without authenticating first. + /// The requested user is already the primary user of the session. + 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); + } + } } } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs index 08481f09fc..d693f90e24 100644 --- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs +++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs @@ -191,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.Session var session = GetSessionFromMessage(message); - if (session != null && session.User != null) + if (session != null && session.UserId.HasValue) { var vals = message.Data.Split('|'); @@ -229,7 +229,7 @@ namespace MediaBrowser.Server.Implementations.Session { var session = GetSessionFromMessage(message); - if (session != null && session.User != null) + if (session != null && session.UserId.HasValue) { var vals = message.Data.Split('|'); @@ -273,7 +273,7 @@ namespace MediaBrowser.Server.Implementations.Session var session = GetSessionFromMessage(message); - if (session != null && session.User != null) + if (session != null && session.UserId.HasValue) { var vals = message.Data.Split('|'); diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 151aedd27f..f47ec6a817 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -254,7 +254,7 @@ namespace MediaBrowser.ServerApplication RegisterSingleInstance(() => new LuceneSearchEngine(ApplicationPaths, LogManager, LibraryManager)); - SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager); + SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager, UserManager); RegisterSingleInstance(SessionManager); HttpServer = ServerFactory.CreateServer(this, LogManager, "Media Browser", "mediabrowser", "dashboard/index.html"); diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js index 73f0207b8d..be2a342c9b 100644 --- a/MediaBrowser.WebDashboard/ApiClient.js +++ b/MediaBrowser.WebDashboard/ApiClient.js @@ -2,7 +2,7 @@ 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 @@ -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 @@ -4208,7 +4208,7 @@ MediaBrowser.SHA1 = function (msg) { } if (matched.platform) { - browser[matched.platform] = true + browser[matched.platform] = true; } // Chrome is Webkit, but Webkit is also Safari. diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config index c0e73ca455..4932cd5c18 100644 --- a/MediaBrowser.WebDashboard/packages.config +++ b/MediaBrowser.WebDashboard/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file