diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 193a23b3e..06e9c80e8 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -286,13 +286,21 @@ namespace MediaBrowser.Api
}
}
- var deviceId = auth["DeviceId"];
- var device = auth["Device"];
- var client = auth["Client"];
+ string deviceId;
+ string device;
+ string client;
+ string version;
- if (!string.IsNullOrEmpty(client) && !string.IsNullOrEmpty(deviceId) && !string.IsNullOrEmpty(device))
+ auth.TryGetValue("DeviceId", out deviceId);
+ auth.TryGetValue("Device", out device);
+ auth.TryGetValue("Client", out client);
+ auth.TryGetValue("Version", out version);
+
+ version = version ?? "0.0.0.0";
+
+ if (!string.IsNullOrEmpty(client) && !string.IsNullOrEmpty(deviceId) && !string.IsNullOrEmpty(device) && !string.IsNullOrEmpty(version))
{
- SessionManager.LogConnectionActivity(client, deviceId, device, user);
+ SessionManager.LogConnectionActivity(client, version, deviceId, device, user);
}
}
}
diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs
index a682d670d..bbd1fd985 100644
--- a/MediaBrowser.Api/SessionsService.cs
+++ b/MediaBrowser.Api/SessionsService.cs
@@ -1,6 +1,5 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Dto;
-using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Session;
@@ -106,6 +105,31 @@ namespace MediaBrowser.Api
public PlayCommand PlayCommand { get; set; }
}
+ [Route("/Sessions/{Id}/Playing/{Command}", "POST")]
+ [Api(("Issues a playstate command to a client"))]
+ public class SendPlaystateCommand : IReturnVoid
+ {
+ ///
+ /// Gets or sets the id.
+ ///
+ /// The id.
+ [ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ public Guid Id { get; set; }
+
+ ///
+ /// Gets or sets the position to seek to
+ ///
+ [ApiMember(Name = "SeekPosition", Description = "The position to seek to.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
+ public long? SeekPosition { get; set; }
+
+ ///
+ /// Gets or sets the play command.
+ ///
+ /// The play command.
+ [ApiMember(Name = "Command", Description = "The command to send - stop, pause, unpause, nexttrack, previoustrack, seek.", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
+ public PlaystateCommand Command { get; set; }
+ }
+
///
/// Class SessionsService
///
@@ -142,6 +166,56 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result.Select(SessionInfoDtoBuilder.GetSessionInfoDto).ToList());
}
+ public void Post(SendPlaystateCommand request)
+ {
+ var task = SendPlaystateCommand(request);
+
+ Task.WaitAll(task);
+ }
+
+ private async Task SendPlaystateCommand(SendPlaystateCommand request)
+ {
+ var session = _sessionManager.Sessions.FirstOrDefault(i => i.Id == request.Id);
+
+ if (session == null)
+ {
+ throw new ResourceNotFoundException(string.Format("Session {0} not found.", request.Id));
+ }
+
+ if (!session.SupportsRemoteControl)
+ {
+ throw new ArgumentException(string.Format("Session {0} does not support remote control.", session.Id));
+ }
+
+ var socket = session.WebSockets.OrderByDescending(i => i.LastActivityDate).FirstOrDefault(i => i.State == WebSocketState.Open);
+
+ if (socket != null)
+ {
+ try
+ {
+ await socket.SendAsync(new WebSocketMessage
+ {
+ MessageType = "Playstate",
+
+ Data = new PlayStateRequest
+ {
+ Command = request.Command,
+ SeekPosition = request.SeekPosition
+ }
+
+ }, CancellationToken.None).ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error sending web socket message", ex);
+ }
+ }
+ else
+ {
+ throw new InvalidOperationException("The requested session does not have an open web socket.");
+ }
+ }
+
///
/// Posts the specified request.
///
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index 6f5ed8cba..951415694 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -586,6 +586,25 @@ namespace MediaBrowser.Api.UserLibrary
Task.WaitAll(task);
}
+ private SessionInfo GetSession()
+ {
+ var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
+
+ string deviceId;
+ string client;
+ string version;
+
+ auth.TryGetValue("DeviceId", out deviceId);
+ auth.TryGetValue("Client", out client);
+ auth.TryGetValue("Version", out version);
+
+ version = version ?? "0.0.0.0";
+
+ return _sessionManager.Sessions.First(i => string.Equals(i.DeviceId, deviceId) &&
+ string.Equals(i.Client, client) &&
+ string.Equals(i.ApplicationVersion, version));
+ }
+
///
/// Posts the specified request.
///
@@ -596,12 +615,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
- var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
-
- if (auth != null)
- {
- _sessionManager.OnPlaybackStart(user, item, auth["Client"], auth["DeviceId"], auth["Device"] ?? string.Empty);
- }
+ _sessionManager.OnPlaybackStart(item, GetSession().Id);
}
///
@@ -614,14 +628,9 @@ namespace MediaBrowser.Api.UserLibrary
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
- var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
+ var task = _sessionManager.OnPlaybackProgress(item, request.PositionTicks, request.IsPaused, GetSession().Id);
- if (auth != null)
- {
- var task = _sessionManager.OnPlaybackProgress(user, item, request.PositionTicks, request.IsPaused, auth["Client"], auth["DeviceId"], auth["Device"] ?? string.Empty);
-
- Task.WaitAll(task);
- }
+ Task.WaitAll(task);
}
///
@@ -634,14 +643,9 @@ namespace MediaBrowser.Api.UserLibrary
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
- var auth = RequestFilterAttribute.GetAuthorization(RequestContext);
+ var task = _sessionManager.OnPlaybackStopped(item, request.PositionTicks, GetSession().Id);
- if (auth != null)
- {
- var task = _sessionManager.OnPlaybackStopped(user, item, request.PositionTicks, auth["Client"], auth["DeviceId"], auth["Device"] ?? string.Empty);
-
- Task.WaitAll(task);
- }
+ Task.WaitAll(task);
}
///
diff --git a/MediaBrowser.Controller/Dto/DtoBuilder.cs b/MediaBrowser.Controller/Dto/DtoBuilder.cs
index d1a0465cd..7167447e4 100644
--- a/MediaBrowser.Controller/Dto/DtoBuilder.cs
+++ b/MediaBrowser.Controller/Dto/DtoBuilder.cs
@@ -381,9 +381,9 @@ namespace MediaBrowser.Controller.Dto
if (parentWithImage != null)
{
- dto.ParentLogoItemId = GetClientItemId(parentWithImage);
+ dto.ParentArtItemId = GetClientItemId(parentWithImage);
- dto.ParentLogoImageTag = GetImageCacheTag(parentWithImage, ImageType.Art, parentWithImage.GetImage(ImageType.Art));
+ dto.ParentArtImageTag = GetImageCacheTag(parentWithImage, ImageType.Art, parentWithImage.GetImage(ImageType.Art));
}
}
diff --git a/MediaBrowser.Controller/Dto/SessionInfoDtoBuilder.cs b/MediaBrowser.Controller/Dto/SessionInfoDtoBuilder.cs
index 27e6a8d95..b2ce4a6ba 100644
--- a/MediaBrowser.Controller/Dto/SessionInfoDtoBuilder.cs
+++ b/MediaBrowser.Controller/Dto/SessionInfoDtoBuilder.cs
@@ -28,7 +28,8 @@ namespace MediaBrowser.Controller.Dto
NowViewingContext = session.NowViewingContext,
NowViewingItemId = session.NowViewingItemId,
NowViewingItemName = session.NowViewingItemName,
- NowViewingItemType = session.NowViewingItemType
+ NowViewingItemType = session.NowViewingItemType,
+ ApplicationVersion = session.ApplicationVersion
};
if (session.NowPlayingItem != null)
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 3d2b46712..814f6d5a1 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -70,7 +70,7 @@
Properties\SharedVersion.cs
-
+
diff --git a/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs b/MediaBrowser.Controller/Notifications/Configuration/IServerConfigurationManager.cs
similarity index 100%
rename from MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs
rename to MediaBrowser.Controller/Notifications/Configuration/IServerConfigurationManager.cs
diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs
index f28721f5f..2af2bbec9 100644
--- a/MediaBrowser.Controller/Session/ISessionManager.cs
+++ b/MediaBrowser.Controller/Session/ISessionManager.cs
@@ -36,49 +36,42 @@ namespace MediaBrowser.Controller.Session
/// Logs the user activity.
///
/// Type of the client.
+ /// The app version.
/// The device id.
/// Name of the device.
/// The user.
/// Task.
/// user
- Task LogConnectionActivity(string clientType, string deviceId, string deviceName, User user);
+ Task LogConnectionActivity(string clientType, string appVersion, string deviceId, string deviceName, User user);
///
/// Used to report that playback has started for an item
///
- /// The user.
/// The item.
- /// Type of the client.
- /// The device id.
- /// Name of the device.
+ /// The session id.
+ /// Task.
///
- Task OnPlaybackStart(User user, BaseItem item, string clientType, string deviceId, string deviceName);
+ Task OnPlaybackStart(BaseItem item, Guid sessionId);
///
/// Used to report playback progress for an item
///
- /// The user.
/// The item.
/// The position ticks.
/// if set to true [is paused].
- /// Type of the client.
- /// The device id.
- /// Name of the device.
+ /// The session id.
/// Task.
///
- Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, bool isPaused, string clientType, string deviceId, string deviceName);
+ Task OnPlaybackProgress(BaseItem item, long? positionTicks, bool isPaused, Guid sessionId);
///
/// Used to report that playback has ended for an item
///
- /// The user.
/// The item.
/// The position ticks.
- /// Type of the client.
- /// The device id.
- /// Name of the device.
+ /// The session id.
/// Task.
///
- Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, string clientType, string deviceId, string deviceName);
+ Task OnPlaybackStopped(BaseItem item, long? positionTicks, Guid sessionId);
}
}
\ No newline at end of file
diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs
index e49b52624..177573de6 100644
--- a/MediaBrowser.Controller/Session/SessionInfo.cs
+++ b/MediaBrowser.Controller/Session/SessionInfo.cs
@@ -101,6 +101,12 @@ namespace MediaBrowser.Controller.Session
/// The web socket.
public List WebSockets { get; set; }
+ ///
+ /// Gets or sets the application version.
+ ///
+ /// The application version.
+ public string ApplicationVersion { get; set; }
+
///
/// Gets a value indicating whether this instance is active.
///
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index 9c534f916..95fea4071 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -268,6 +268,9 @@
Querying\ThemeSongsResult.cs
+
+ Querying\UserQuery.cs
+
Search\SearchHint.cs
@@ -286,8 +289,8 @@
Session\PlayRequest.cs
-
- Session\PlaystateRequest.cs
+
+ Session\PlaystateCommand.cs
Session\SessionInfoDto.cs
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 4ec7b14e1..990f63f84 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -100,6 +100,12 @@ namespace MediaBrowser.Model.ApiClient
/// Task{UserDto[]}.
Task GetUsersAsync();
+ ///
+ /// Gets the public users async.
+ ///
+ /// Task{UserDto[]}.
+ Task GetPublicUsersAsync();
+
///
/// Gets active client sessions.
///
@@ -358,6 +364,14 @@ namespace MediaBrowser.Model.ApiClient
/// Task.
Task SendBrowseCommandAsync(string sessionId, string itemId, string itemName, string itemType, string context);
+ ///
+ /// Sends the playstate command async.
+ ///
+ /// The session id.
+ /// The request.
+ /// Task.
+ Task SendPlaystateCommandAsync(string sessionId, PlayStateRequest request);
+
///
/// Sends the play command async.
///
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index da01da475..14313d421 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -72,9 +72,10 @@
+
-
+
diff --git a/MediaBrowser.Model/Querying/UserQuery.cs b/MediaBrowser.Model/Querying/UserQuery.cs
new file mode 100644
index 000000000..48dbd30aa
--- /dev/null
+++ b/MediaBrowser.Model/Querying/UserQuery.cs
@@ -0,0 +1,9 @@
+
+namespace MediaBrowser.Model.Querying
+{
+ public class UserQuery
+ {
+ public bool? IsHidden { get; set; }
+ public bool? IsDisabled { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Session/PlaystateRequest.cs b/MediaBrowser.Model/Session/PlaystateCommand.cs
similarity index 66%
rename from MediaBrowser.Model/Session/PlaystateRequest.cs
rename to MediaBrowser.Model/Session/PlaystateCommand.cs
index 78551060f..01f7068ac 100644
--- a/MediaBrowser.Model/Session/PlaystateRequest.cs
+++ b/MediaBrowser.Model/Session/PlaystateCommand.cs
@@ -1,25 +1,6 @@
namespace MediaBrowser.Model.Session
{
- ///
- /// Class PlaystateRequest
- ///
- public class PlaystateRequest
- {
- ///
- /// Gets or sets the command.
- ///
- /// The command.
- public PlaystateCommand Command { get; set; }
-
- ///
- /// Gets or sets the seek position.
- /// Only applicable to seek commands.
- ///
- /// The seek position.
- public long? SeekPosition { get; set; }
- }
-
///
/// Enum PlaystateCommand
///
@@ -50,4 +31,11 @@ namespace MediaBrowser.Model.Session
///
Seek
}
+
+ public class PlayStateRequest
+ {
+ public PlaystateCommand Command { get; set; }
+
+ public long? SeekPosition { get; set; }
+ }
}
diff --git a/MediaBrowser.Model/Session/SessionInfoDto.cs b/MediaBrowser.Model/Session/SessionInfoDto.cs
index 294e6a264..93d531806 100644
--- a/MediaBrowser.Model/Session/SessionInfoDto.cs
+++ b/MediaBrowser.Model/Session/SessionInfoDto.cs
@@ -22,6 +22,12 @@ namespace MediaBrowser.Model.Session
///
/// The name of the user.
public string UserName { get; set; }
+
+ ///
+ /// Gets or sets the application version.
+ ///
+ /// The application version.
+ public string ApplicationVersion { get; set; }
///
/// Gets or sets the type of the client.
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
index 79ea89ac6..0aaafec83 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
+++ b/MediaBrowser.Server.Implementations/ScheduledTasks/ChapterImagesTask.cs
@@ -121,7 +121,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
}
}
}
-
+
///
/// Creates the triggers that define when the task will run
///
@@ -148,13 +148,15 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
var numComplete = 0;
- var failHistoryPath = Path.Combine(_kernel.FFMpegManager.VideoImagesDataPath, "failures.json");
+ var failHistoryPath = Path.Combine(_kernel.FFMpegManager.VideoImagesDataPath, "failures.txt");
List previouslyFailedImages;
-
+
try
{
- previouslyFailedImages = _jsonSerializer.DeserializeFromFile>(failHistoryPath);
+ previouslyFailedImages = File.ReadAllText(failHistoryPath)
+ .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
+ .ToList();
}
catch (FileNotFoundException)
{
@@ -184,7 +186,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
Directory.CreateDirectory(parentPath);
}
- _jsonSerializer.SerializeToFile(previouslyFailedImages, failHistoryPath);
+ File.WriteAllText(failHistoryPath, string.Join("|", previouslyFailedImages.ToArray()));
}
numComplete++;
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index d9f28915a..fde1eba9d 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -94,13 +94,32 @@ namespace MediaBrowser.Server.Implementations.Session
/// Logs the user activity.
///
/// Type of the client.
+ /// The app version.
/// The device id.
/// Name of the device.
/// The user.
/// Task.
+ ///
/// user
- public Task LogConnectionActivity(string clientType, string deviceId, string deviceName, User user)
+ public async Task LogConnectionActivity(string clientType, string appVersion, string deviceId, string deviceName, User user)
{
+ if (string.IsNullOrEmpty(clientType))
+ {
+ throw new ArgumentNullException("clientType");
+ }
+ if (string.IsNullOrEmpty(appVersion))
+ {
+ throw new ArgumentNullException("appVersion");
+ }
+ if (string.IsNullOrEmpty(deviceId))
+ {
+ throw new ArgumentNullException("deviceId");
+ }
+ if (string.IsNullOrEmpty(deviceName))
+ {
+ throw new ArgumentNullException("deviceName");
+ }
+
if (user != null && user.Configuration.IsDisabled)
{
throw new UnauthorizedAccessException(string.Format("The {0} account is currently disabled. Please consult with your administrator.", user.Name));
@@ -108,11 +127,13 @@ namespace MediaBrowser.Server.Implementations.Session
var activityDate = DateTime.UtcNow;
- GetConnection(clientType, deviceId, deviceName, user).LastActivityDate = activityDate;
+ var session = GetSessionInfo(clientType, appVersion, deviceId, deviceName, user);
+
+ session.LastActivityDate = activityDate;
if (user == null)
{
- return _trueTaskResult;
+ return session;
}
var lastActivityDate = user.LastActivityDate;
@@ -122,50 +143,42 @@ namespace MediaBrowser.Server.Implementations.Session
// Don't log in the db anymore frequently than 10 seconds
if (lastActivityDate.HasValue && (activityDate - lastActivityDate.Value).TotalSeconds < 10)
{
- return _trueTaskResult;
+ return session;
}
// Save this directly. No need to fire off all the events for this.
- return _userRepository.SaveUser(user, CancellationToken.None);
+ await _userRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
+
+ return session;
}
///
/// Updates the now playing item id.
///
- /// The user.
- /// Type of the client.
- /// The device id.
- /// Name of the device.
+ /// The session.
/// The item.
/// if set to true [is paused].
/// The current position ticks.
- private void UpdateNowPlayingItemId(User user, string clientType, string deviceId, string deviceName, BaseItem item, bool isPaused, long? currentPositionTicks = null)
+ private void UpdateNowPlayingItem(SessionInfo session, BaseItem item, bool isPaused, long? currentPositionTicks = null)
{
- var conn = GetConnection(clientType, deviceId, deviceName, user);
-
- conn.IsPaused = isPaused;
- conn.NowPlayingPositionTicks = currentPositionTicks;
- conn.NowPlayingItem = item;
- conn.LastActivityDate = DateTime.UtcNow;
+ session.IsPaused = isPaused;
+ session.NowPlayingPositionTicks = currentPositionTicks;
+ session.NowPlayingItem = item;
+ session.LastActivityDate = DateTime.UtcNow;
}
///
/// Removes the now playing item id.
///
- /// The user.
- /// Type of the client.
- /// The device id.
- /// Name of the device.
+ /// The session.
/// The item.
- private void RemoveNowPlayingItemId(User user, string clientType, string deviceId, string deviceName, BaseItem item)
+ private void RemoveNowPlayingItem(SessionInfo session, BaseItem item)
{
- var conn = GetConnection(clientType, deviceId, deviceName, user);
-
- if (conn.NowPlayingItem != null && conn.NowPlayingItem.Id == item.Id)
+ if (session.NowPlayingItem != null && session.NowPlayingItem.Id == item.Id)
{
- conn.NowPlayingItem = null;
- conn.NowPlayingPositionTicks = null;
- conn.IsPaused = null;
+ session.NowPlayingItem = null;
+ session.NowPlayingPositionTicks = null;
+ session.IsPaused = null;
}
}
@@ -173,23 +186,24 @@ namespace MediaBrowser.Server.Implementations.Session
/// Gets the connection.
///
/// Type of the client.
+ /// The app version.
/// The device id.
/// Name of the device.
/// The user.
/// SessionInfo.
- private SessionInfo GetConnection(string clientType, string deviceId, string deviceName, User user)
+ private SessionInfo GetSessionInfo(string clientType, string appVersion, string deviceId, string deviceName, User user)
{
- var key = clientType + deviceId;
+ var key = clientType + deviceId + appVersion;
var connection = _activeConnections.GetOrAdd(key, keyName => new SessionInfo
{
Client = clientType,
DeviceId = deviceId,
+ ApplicationVersion = appVersion,
Id = Guid.NewGuid()
});
connection.DeviceName = deviceName;
-
connection.User = user;
return connection;
@@ -198,28 +212,25 @@ namespace MediaBrowser.Server.Implementations.Session
///
/// Used to report that playback has started for an item
///
- /// The user.
/// The item.
- /// Type of the client.
- /// The device id.
- /// Name of the device.
- ///
- ///
- public async Task OnPlaybackStart(User user, BaseItem item, string clientType, string deviceId, string deviceName)
+ /// The session id.
+ /// Task.
+ ///
+ public async Task OnPlaybackStart(BaseItem item, Guid sessionId)
{
- if (user == null)
- {
- throw new ArgumentNullException();
- }
if (item == null)
{
throw new ArgumentNullException();
}
- UpdateNowPlayingItemId(user, clientType, deviceId, deviceName, item, false);
+ var session = Sessions.First(i => i.Id.Equals(sessionId));
+
+ UpdateNowPlayingItem(session, item, false);
var key = item.GetUserDataKey();
+ var user = session.User;
+
var data = _userDataRepository.GetUserData(user.Id, key);
data.PlayCount++;
@@ -248,27 +259,25 @@ namespace MediaBrowser.Server.Implementations.Session
/// The item.
/// The position ticks.
/// if set to true [is paused].
- /// Type of the client.
- /// The device id.
- /// Name of the device.
+ /// The session id.
/// Task.
///
///
- public async Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, bool isPaused, string clientType, string deviceId, string deviceName)
+ public async Task OnPlaybackProgress(BaseItem item, long? positionTicks, bool isPaused, Guid sessionId)
{
- if (user == null)
- {
- throw new ArgumentNullException();
- }
if (item == null)
{
throw new ArgumentNullException();
}
- UpdateNowPlayingItemId(user, clientType, deviceId, deviceName, item, isPaused, positionTicks);
+ var session = Sessions.First(i => i.Id.Equals(sessionId));
+
+ UpdateNowPlayingItem(session, item, isPaused, positionTicks);
var key = item.GetUserDataKey();
+ var user = session.User;
+
if (positionTicks.HasValue)
{
var data = _userDataRepository.GetUserData(user.Id, key);
@@ -282,36 +291,33 @@ namespace MediaBrowser.Server.Implementations.Session
Item = item,
User = user,
PlaybackPositionTicks = positionTicks
+
}, _logger);
}
///
/// Used to report that playback has ended for an item
///
- /// The user.
/// The item.
/// The position ticks.
- /// Type of the client.
- /// The device id.
- /// Name of the device.
+ /// The session id.
/// Task.
- ///
- ///
- public async Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, string clientType, string deviceId, string deviceName)
+ ///
+ public async Task OnPlaybackStopped(BaseItem item, long? positionTicks, Guid sessionId)
{
- if (user == null)
- {
- throw new ArgumentNullException();
- }
if (item == null)
{
throw new ArgumentNullException();
}
- RemoveNowPlayingItemId(user, clientType, deviceId, deviceName, item);
+ var session = Sessions.First(i => i.Id.Equals(sessionId));
+
+ RemoveNowPlayingItem(session, item);
var key = item.GetUserDataKey();
+ var user = session.User;
+
var data = _userDataRepository.GetUserData(user.Id, key);
if (positionTicks.HasValue)
diff --git a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs
index c649fd474..d712bbc60 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionWebSocketListener.cs
@@ -103,7 +103,7 @@ namespace MediaBrowser.Server.Implementations.Session
{
var item = DtoBuilder.GetItemByClientId(message.Data, _userManager, _libraryManager);
- _sessionManager.OnPlaybackStart(_userManager.GetUserById(session.User.Id), item, session.Client, session.DeviceId, session.DeviceName);
+ _sessionManager.OnPlaybackStart(item, session.Id);
}
}
else if (string.Equals(message.MessageType, "PlaybackProgress", StringComparison.OrdinalIgnoreCase))
@@ -130,7 +130,7 @@ namespace MediaBrowser.Server.Implementations.Session
var isPaused = vals.Length > 2 && string.Equals(vals[2], "true", StringComparison.OrdinalIgnoreCase);
- _sessionManager.OnPlaybackProgress(_userManager.GetUserById(session.User.Id), item, positionTicks, isPaused, session.Client, session.DeviceId, session.DeviceName);
+ _sessionManager.OnPlaybackProgress(item, positionTicks, isPaused, session.Id);
}
}
else if (string.Equals(message.MessageType, "PlaybackStopped", StringComparison.OrdinalIgnoreCase))
@@ -155,7 +155,7 @@ namespace MediaBrowser.Server.Implementations.Session
}
}
- _sessionManager.OnPlaybackStopped(_userManager.GetUserById(session.User.Id), item, positionTicks, session.Client, session.DeviceId, session.DeviceName);
+ _sessionManager.OnPlaybackStopped(item, positionTicks, session.Id);
}
}
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 89aaec4b2..184354a22 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -512,6 +512,12 @@ namespace MediaBrowser.WebDashboard.Api
var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine);
+ var versionString = string.Format("window.dashboardVersion='{0}';", GetType().Assembly.GetName().Version);
+ var versionBytes = Encoding.UTF8.GetBytes(versionString);
+
+ await memoryStream.WriteAsync(versionBytes, 0, versionBytes.Length).ConfigureAwait(false);
+ await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false);
+
await AppendResource(memoryStream, "thirdparty/autoNumeric.js", newLineBytes).ConfigureAwait(false);
await AppendResource(memoryStream, "thirdparty/html5slider.js", newLineBytes).ConfigureAwait(false);
diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js
index 8b602610a..3117b4b00 100644
--- a/MediaBrowser.WebDashboard/ApiClient.js
+++ b/MediaBrowser.WebDashboard/ApiClient.js
@@ -10,8 +10,9 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
* @param {String} serverHostName
* @param {String} serverPortNumber
* @param {String} clientName
+ * @param {String} applicationVersion
*/
- return function (serverProtocol, serverHostName, serverPortNumber, clientName) {
+ return function (serverProtocol, serverHostName, serverPortNumber, clientName, applicationVersion) {
if (!serverProtocol) {
throw new Error("Must supply a serverProtocol, e.g. http:");
@@ -120,7 +121,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
if (clientName) {
- var auth = 'MediaBrowser Client="' + clientName + '", Device="' + deviceName + '", DeviceId="' + deviceId + '"';
+ var auth = 'MediaBrowser Client="' + clientName + '", Device="' + deviceName + '", DeviceId="' + deviceId + '", Version="' + applicationVersion + '"';
if (currentUserId) {
auth += ', UserId="' + currentUserId + '"';
@@ -3277,11 +3278,11 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
/**
* Provides a friendly way to create an api client instance using information from the browser's current url
*/
-MediaBrowser.ApiClient.create = function (clientName) {
+MediaBrowser.ApiClient.create = function (clientName, applicationVersion) {
var loc = window.location;
- return new MediaBrowser.ApiClient(loc.protocol, loc.hostname, loc.port, clientName);
+ return new MediaBrowser.ApiClient(loc.protocol, loc.hostname, loc.port, clientName, applicationVersion);
};
/**
diff --git a/MediaBrowser.WebDashboard/packages.config b/MediaBrowser.WebDashboard/packages.config
index a1b6ec005..bb1b35f24 100644
--- a/MediaBrowser.WebDashboard/packages.config
+++ b/MediaBrowser.WebDashboard/packages.config
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file