Display client version in the dashboard
This commit is contained in:
parent
48265fefa4
commit
66624293ac
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the id.
|
||||
/// </summary>
|
||||
/// <value>The id.</value>
|
||||
[ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the position to seek to
|
||||
/// </summary>
|
||||
[ApiMember(Name = "SeekPosition", Description = "The position to seek to.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public long? SeekPosition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the play command.
|
||||
/// </summary>
|
||||
/// <value>The play command.</value>
|
||||
[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; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class SessionsService
|
||||
/// </summary>
|
||||
|
@ -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<PlayStateRequest>
|
||||
{
|
||||
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.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the specified request.
|
||||
/// </summary>
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts the specified request.
|
||||
/// </summary>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
<Compile Include="..\SharedVersion.cs">
|
||||
<Link>Properties\SharedVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Configuration\IServerConfigurationManager.cs" />
|
||||
<Compile Include="Notifications\Configuration\IServerConfigurationManager.cs" />
|
||||
<Compile Include="Dto\SessionInfoDtoBuilder.cs" />
|
||||
<Compile Include="Entities\Audio\MusicAlbumDisc.cs" />
|
||||
<Compile Include="Entities\Audio\MusicGenre.cs" />
|
||||
|
|
|
@ -36,49 +36,42 @@ namespace MediaBrowser.Controller.Session
|
|||
/// Logs the user activity.
|
||||
/// </summary>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="appVersion">The app version.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
Task LogConnectionActivity(string clientType, string deviceId, string deviceName, User user);
|
||||
Task<SessionInfo> LogConnectionActivity(string clientType, string appVersion, string deviceId, string deviceName, User user);
|
||||
|
||||
/// <summary>
|
||||
/// Used to report that playback has started for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
Task OnPlaybackStart(User user, BaseItem item, string clientType, string deviceId, string deviceName);
|
||||
Task OnPlaybackStart(BaseItem item, Guid sessionId);
|
||||
|
||||
/// <summary>
|
||||
/// Used to report playback progress for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="isPaused">if set to <c>true</c> [is paused].</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
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);
|
||||
|
||||
/// <summary>
|
||||
/// Used to report that playback has ended for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, string clientType, string deviceId, string deviceName);
|
||||
Task OnPlaybackStopped(BaseItem item, long? positionTicks, Guid sessionId);
|
||||
}
|
||||
}
|
|
@ -101,6 +101,12 @@ namespace MediaBrowser.Controller.Session
|
|||
/// <value>The web socket.</value>
|
||||
public List<IWebSocketConnection> WebSockets { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application version.
|
||||
/// </summary>
|
||||
/// <value>The application version.</value>
|
||||
public string ApplicationVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this instance is active.
|
||||
/// </summary>
|
||||
|
|
|
@ -268,6 +268,9 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Querying\ThemeSongsResult.cs">
|
||||
<Link>Querying\ThemeSongsResult.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Querying\UserQuery.cs">
|
||||
<Link>Querying\UserQuery.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Search\SearchHint.cs">
|
||||
<Link>Search\SearchHint.cs</Link>
|
||||
</Compile>
|
||||
|
@ -286,8 +289,8 @@
|
|||
<Compile Include="..\MediaBrowser.Model\Session\PlayRequest.cs">
|
||||
<Link>Session\PlayRequest.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Session\PlaystateRequest.cs">
|
||||
<Link>Session\PlaystateRequest.cs</Link>
|
||||
<Compile Include="..\MediaBrowser.Model\Session\PlaystateCommand.cs">
|
||||
<Link>Session\PlaystateCommand.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\MediaBrowser.Model\Session\SessionInfoDto.cs">
|
||||
<Link>Session\SessionInfoDto.cs</Link>
|
||||
|
|
|
@ -100,6 +100,12 @@ namespace MediaBrowser.Model.ApiClient
|
|||
/// <returns>Task{UserDto[]}.</returns>
|
||||
Task<UserDto[]> GetUsersAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the public users async.
|
||||
/// </summary>
|
||||
/// <returns>Task{UserDto[]}.</returns>
|
||||
Task<UserDto[]> GetPublicUsersAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Gets active client sessions.
|
||||
/// </summary>
|
||||
|
@ -358,6 +364,14 @@ namespace MediaBrowser.Model.ApiClient
|
|||
/// <returns>Task.</returns>
|
||||
Task SendBrowseCommandAsync(string sessionId, string itemId, string itemName, string itemType, string context);
|
||||
|
||||
/// <summary>
|
||||
/// Sends the playstate command async.
|
||||
/// </summary>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <param name="request">The request.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task SendPlaystateCommandAsync(string sessionId, PlayStateRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Sends the play command async.
|
||||
/// </summary>
|
||||
|
|
|
@ -72,9 +72,10 @@
|
|||
<Compile Include="Entities\BaseItemInfo.cs" />
|
||||
<Compile Include="Querying\NextUpQuery.cs" />
|
||||
<Compile Include="Querying\SimilarItemsQuery.cs" />
|
||||
<Compile Include="Querying\UserQuery.cs" />
|
||||
<Compile Include="Session\BrowseRequest.cs" />
|
||||
<Compile Include="Session\PlayRequest.cs" />
|
||||
<Compile Include="Session\PlaystateRequest.cs" />
|
||||
<Compile Include="Session\PlaystateCommand.cs" />
|
||||
<Compile Include="Entities\ImageDownloadOptions.cs" />
|
||||
<Compile Include="Logging\ILogManager.cs" />
|
||||
<Compile Include="MediaInfo\BlurayDiscInfo.cs" />
|
||||
|
|
9
MediaBrowser.Model/Querying/UserQuery.cs
Normal file
9
MediaBrowser.Model/Querying/UserQuery.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
namespace MediaBrowser.Model.Querying
|
||||
{
|
||||
public class UserQuery
|
||||
{
|
||||
public bool? IsHidden { get; set; }
|
||||
public bool? IsDisabled { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,25 +1,6 @@
|
|||
|
||||
namespace MediaBrowser.Model.Session
|
||||
{
|
||||
/// <summary>
|
||||
/// Class PlaystateRequest
|
||||
/// </summary>
|
||||
public class PlaystateRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the command.
|
||||
/// </summary>
|
||||
/// <value>The command.</value>
|
||||
public PlaystateCommand Command { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the seek position.
|
||||
/// Only applicable to seek commands.
|
||||
/// </summary>
|
||||
/// <value>The seek position.</value>
|
||||
public long? SeekPosition { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enum PlaystateCommand
|
||||
/// </summary>
|
||||
|
@ -50,4 +31,11 @@ namespace MediaBrowser.Model.Session
|
|||
/// </summary>
|
||||
Seek
|
||||
}
|
||||
|
||||
public class PlayStateRequest
|
||||
{
|
||||
public PlaystateCommand Command { get; set; }
|
||||
|
||||
public long? SeekPosition { get; set; }
|
||||
}
|
||||
}
|
|
@ -22,6 +22,12 @@ namespace MediaBrowser.Model.Session
|
|||
/// </summary>
|
||||
/// <value>The name of the user.</value>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the application version.
|
||||
/// </summary>
|
||||
/// <value>The application version.</value>
|
||||
public string ApplicationVersion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the client.
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates the triggers that define when the task will run
|
||||
/// </summary>
|
||||
|
@ -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<string> previouslyFailedImages;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
previouslyFailedImages = _jsonSerializer.DeserializeFromFile<List<string>>(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++;
|
||||
|
|
|
@ -94,13 +94,32 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
/// Logs the user activity.
|
||||
/// </summary>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="appVersion">The app version.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.UnauthorizedAccessException"></exception>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
public Task LogConnectionActivity(string clientType, string deviceId, string deviceName, User user)
|
||||
public async Task<SessionInfo> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the now playing item id.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="session">The session.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="isPaused">if set to <c>true</c> [is paused].</param>
|
||||
/// <param name="currentPositionTicks">The current position ticks.</param>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the now playing item id.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="session">The session.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
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.
|
||||
/// </summary>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="appVersion">The app version.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>SessionInfo.</returns>
|
||||
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
|
|||
/// <summary>
|
||||
/// Used to report that playback has started for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// </exception>
|
||||
public async Task OnPlaybackStart(User user, BaseItem item, string clientType, string deviceId, string deviceName)
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
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
|
|||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="isPaused">if set to <c>true</c> [is paused].</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// </exception>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to report that playback has ended for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceId">The device id.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="sessionId">The session id.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">
|
||||
/// </exception>
|
||||
public async Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, string clientType, string deviceId, string deviceName)
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.139" targetFramework="net45" />
|
||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.141" targetFramework="net45" />
|
||||
<package id="ServiceStack.Common" version="3.9.54" targetFramework="net45" />
|
||||
<package id="ServiceStack.Text" version="3.9.54" targetFramework="net45" />
|
||||
</packages>
|
Loading…
Reference in New Issue
Block a user