diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
new file mode 100644
index 0000000000..d3e8339c58
--- /dev/null
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -0,0 +1,118 @@
+using System.Collections.Generic;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Connectivity;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Server.Implementations.HttpServer;
+using ServiceStack.Common.Web;
+using ServiceStack.ServiceHost;
+using System;
+
+namespace MediaBrowser.Api
+{
+ ///
+ /// Class BaseApiService
+ ///
+ [RequestFilter]
+ public class BaseApiService : BaseRestService
+ {
+ }
+
+ ///
+ /// Class RequestFilterAttribute
+ ///
+ public class RequestFilterAttribute : Attribute, IHasRequestFilter
+ {
+ //This property will be resolved by the IoC container
+ ///
+ /// Gets or sets the user manager.
+ ///
+ /// The user manager.
+ public IUserManager UserManager { get; set; }
+
+ ///
+ /// Gets or sets the logger.
+ ///
+ /// The logger.
+ public ILogger Logger { get; set; }
+
+ ///
+ /// The request filter is executed before the service.
+ ///
+ /// The http request wrapper
+ /// The http response wrapper
+ /// The request DTO
+ public void RequestFilter(IHttpRequest request, IHttpResponse response, object requestDto)
+ {
+ //This code is executed before the service
+
+ var auth = GetAuthorization(request);
+
+ if (auth != null)
+ {
+ var user = UserManager.GetUserById(new Guid(auth["UserId"]));
+
+ ClientType clientType;
+
+ Enum.TryParse(auth["Client"] ?? string.Empty, out clientType);
+
+ UserManager.LogUserActivity(user, clientType, auth["DeviceId"], auth["Device"] ?? string.Empty);
+ }
+ }
+
+ ///
+ /// Gets the auth.
+ ///
+ /// The HTTP req.
+ /// Dictionary{System.StringSystem.String}.
+ public static Dictionary GetAuthorization(IHttpRequest httpReq)
+ {
+ var auth = httpReq.Headers[HttpHeaders.Authorization];
+ if (auth == null) return null;
+
+ var parts = auth.Split(' ');
+
+ // There should be at least to parts
+ if (parts.Length < 2) return null;
+
+ // It has to be a digest request
+ if (!string.Equals(parts[0], "MediaBrowser", StringComparison.OrdinalIgnoreCase))
+ {
+ return null;
+ }
+
+ // Remove uptil the first space
+ auth = auth.Substring(auth.IndexOf(' '));
+ parts = auth.Split(',');
+
+ var result = new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ foreach (var item in parts)
+ {
+ var param = item.Trim().Split(new[] { '=' }, 2);
+ result.Add(param[0], param[1].Trim(new[] { '"' }));
+ }
+
+ return result;
+ }
+
+ ///
+ /// A new shallow copy of this filter is used on every request.
+ ///
+ /// IHasRequestFilter.
+ public IHasRequestFilter Copy()
+ {
+ return this;
+ }
+
+ ///
+ /// Order in which Request Filters are executed.
+ /// <0 Executed before global request filters
+ /// >0 Executed after global request filters
+ ///
+ /// The priority.
+ public int Priority
+ {
+ get { return 0; }
+ }
+ }
+}
diff --git a/MediaBrowser.Api/EnvironmentService.cs b/MediaBrowser.Api/EnvironmentService.cs
index b65162cfa2..d35d485360 100644
--- a/MediaBrowser.Api/EnvironmentService.cs
+++ b/MediaBrowser.Api/EnvironmentService.cs
@@ -75,7 +75,7 @@ namespace MediaBrowser.Api
///
/// Class EnvironmentService
///
- public class EnvironmentService : BaseRestService
+ public class EnvironmentService : BaseApiService
{
///
/// The _network manager
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index c854c47f51..90100dfa7a 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -150,7 +150,7 @@ namespace MediaBrowser.Api.Images
///
/// Class ImageService
///
- public class ImageService : BaseRestService
+ public class ImageService : BaseApiService
{
///
/// The _user manager
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index 9d1df4ccba..73f2243f2e 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -98,7 +98,7 @@ namespace MediaBrowser.Api.Library
///
/// Class LibraryService
///
- public class LibraryService : BaseRestService
+ public class LibraryService : BaseApiService
{
///
/// The _app host
diff --git a/MediaBrowser.Api/Library/LibraryStructureService.cs b/MediaBrowser.Api/Library/LibraryStructureService.cs
index 0ae73ed457..072e37e683 100644
--- a/MediaBrowser.Api/Library/LibraryStructureService.cs
+++ b/MediaBrowser.Api/Library/LibraryStructureService.cs
@@ -129,7 +129,7 @@ namespace MediaBrowser.Api.Library
///
/// Class LibraryStructureService
///
- public class LibraryStructureService : BaseRestService
+ public class LibraryStructureService : BaseApiService
{
///
/// The _app paths
diff --git a/MediaBrowser.Api/LocalizationService.cs b/MediaBrowser.Api/LocalizationService.cs
index ed5de76835..b7788326e6 100644
--- a/MediaBrowser.Api/LocalizationService.cs
+++ b/MediaBrowser.Api/LocalizationService.cs
@@ -40,7 +40,7 @@ namespace MediaBrowser.Api
///
/// Class CulturesService
///
- public class LocalizationService : BaseRestService
+ public class LocalizationService : BaseApiService
{
///
/// Gets the specified request.
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 58564fc900..fe5004f87a 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -81,6 +81,7 @@
Properties\SharedVersion.cs
+
diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs
index b09830c546..a741eff410 100644
--- a/MediaBrowser.Api/PackageService.cs
+++ b/MediaBrowser.Api/PackageService.cs
@@ -104,7 +104,7 @@ namespace MediaBrowser.Api
///
/// Class PackageService
///
- public class PackageService : BaseRestService
+ public class PackageService : BaseApiService
{
private readonly IInstallationManager _installationManager;
private readonly IApplicationHost _appHost;
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 570c6eea05..03068c4c7f 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -21,7 +21,7 @@ namespace MediaBrowser.Api.Playback
///
/// Class BaseStreamingService
///
- public abstract class BaseStreamingService : BaseRestService
+ public abstract class BaseStreamingService : BaseApiService
{
///
/// Gets or sets the application paths.
diff --git a/MediaBrowser.Api/PluginService.cs b/MediaBrowser.Api/PluginService.cs
index 3f41460203..074d51b447 100644
--- a/MediaBrowser.Api/PluginService.cs
+++ b/MediaBrowser.Api/PluginService.cs
@@ -126,7 +126,7 @@ namespace MediaBrowser.Api
///
/// Class PluginsService
///
- public class PluginService : BaseRestService
+ public class PluginService : BaseApiService
{
///
/// The _json serializer
diff --git a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
index 204610cddf..a20013b128 100644
--- a/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
+++ b/MediaBrowser.Api/ScheduledTasks/ScheduledTaskService.cs
@@ -83,7 +83,7 @@ namespace MediaBrowser.Api.ScheduledTasks
///
/// Class ScheduledTasksService
///
- public class ScheduledTaskService : BaseRestService
+ public class ScheduledTaskService : BaseApiService
{
///
/// Gets or sets the task manager.
diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs
index a0137652e9..cddcd199c9 100644
--- a/MediaBrowser.Api/SystemService.cs
+++ b/MediaBrowser.Api/SystemService.cs
@@ -4,7 +4,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.System;
-using MediaBrowser.Server.Implementations.HttpServer;
using ServiceStack.ServiceHost;
using System;
using System.IO;
@@ -59,7 +58,7 @@ namespace MediaBrowser.Api
///
/// Class SystemInfoService
///
- public class SystemService : BaseRestService
+ public class SystemService : BaseApiService
{
///
/// The _json serializer
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index 0a013e90a8..ff914c8c54 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -16,7 +16,7 @@ namespace MediaBrowser.Api.UserLibrary
/// Class BaseItemsByNameService
///
/// The type of the T item type.
- public abstract class BaseItemsByNameService : BaseRestService
+ public abstract class BaseItemsByNameService : BaseApiService
where TItemType : BaseItem
{
///
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index e5e88b4388..09796c67f1 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -112,7 +112,7 @@ namespace MediaBrowser.Api.UserLibrary
///
/// Class ItemsService
///
- public class ItemsService : BaseRestService
+ public class ItemsService : BaseApiService
{
///
/// The _user manager
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index 9e2d54448c..3e0c2a960f 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -6,6 +6,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Server.Implementations.HttpServer;
+using MediaBrowser.Server.Implementations.Library;
using ServiceStack.ServiceHost;
using ServiceStack.Text.Controller;
using System;
@@ -347,7 +348,7 @@ namespace MediaBrowser.Api.UserLibrary
///
/// Class UserLibraryService
///
- public class UserLibraryService : BaseRestService
+ public class UserLibraryService : BaseApiService
{
///
/// The _user manager
@@ -592,7 +593,16 @@ namespace MediaBrowser.Api.UserLibrary
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
- _userManager.OnPlaybackStart(user, item, ClientType.Other, string.Empty);
+ var auth = RequestFilterAttribute.GetAuthorization(Request);
+
+ if (auth != null)
+ {
+ ClientType clientType;
+
+ Enum.TryParse(auth["Client"] ?? string.Empty, out clientType);
+
+ _userManager.OnPlaybackStart(user, item, clientType, auth["DeviceId"], auth["Device"] ?? string.Empty);
+ }
}
///
@@ -605,9 +615,18 @@ namespace MediaBrowser.Api.UserLibrary
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
- var task = _userManager.OnPlaybackProgress(user, item, request.PositionTicks, ClientType.Other, string.Empty);
+ var auth = RequestFilterAttribute.GetAuthorization(Request);
- Task.WaitAll(task);
+ if (auth != null)
+ {
+ ClientType clientType;
+
+ Enum.TryParse(auth["Client"] ?? string.Empty, out clientType);
+
+ var task = _userManager.OnPlaybackProgress(user, item, request.PositionTicks, clientType, auth["DeviceId"], auth["Device"] ?? string.Empty);
+
+ Task.WaitAll(task);
+ }
}
///
@@ -620,9 +639,18 @@ namespace MediaBrowser.Api.UserLibrary
var item = DtoBuilder.GetItemByClientId(request.Id, _userManager, _libraryManager, user.Id);
- var task = _userManager.OnPlaybackStopped(user, item, request.PositionTicks, ClientType.Other, string.Empty);
+ var auth = RequestFilterAttribute.GetAuthorization(Request);
- Task.WaitAll(task);
+ if (auth != null)
+ {
+ ClientType clientType;
+
+ Enum.TryParse(auth["Client"] ?? string.Empty, out clientType);
+
+ var task = _userManager.OnPlaybackStopped(user, item, request.PositionTicks, clientType, auth["DeviceId"], auth["Device"] ?? string.Empty);
+
+ Task.WaitAll(task);
+ }
}
///
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 1bb1f2e412..b0a5bf4ebb 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -126,7 +126,7 @@ namespace MediaBrowser.Api
///
/// Class UsersService
///
- public class UserService : BaseRestService
+ public class UserService : BaseApiService
{
///
/// The _XML serializer
diff --git a/MediaBrowser.Api/WeatherService.cs b/MediaBrowser.Api/WeatherService.cs
index f2ba68113e..2b1eb53b74 100644
--- a/MediaBrowser.Api/WeatherService.cs
+++ b/MediaBrowser.Api/WeatherService.cs
@@ -25,7 +25,7 @@ namespace MediaBrowser.Api
///
/// Class WeatherService
///
- public class WeatherService : BaseRestService
+ public class WeatherService : BaseApiService
{
///
/// Gets the specified request.
diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index 1a2c1482ca..f1cef1d660 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -69,10 +69,11 @@ namespace MediaBrowser.Controller.Library
///
/// The user.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// Task.
/// user
- Task LogUserActivity(User user, ClientType clientType, string deviceName);
+ Task LogUserActivity(User user, ClientType clientType, string deviceId, string deviceName);
///
/// Refreshes metadata for each user
@@ -124,9 +125,10 @@ namespace MediaBrowser.Controller.Library
/// The user.
/// The item.
/// Type of the client.
+ /// The device id.
/// Name of the device.
///
- void OnPlaybackStart(User user, BaseItem item, ClientType clientType, string deviceName);
+ void OnPlaybackStart(User user, BaseItem item, ClientType clientType, string deviceId, string deviceName);
///
/// Used to report playback progress for an item
@@ -135,10 +137,11 @@ namespace MediaBrowser.Controller.Library
/// The item.
/// The position ticks.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// Task.
///
- Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName);
+ Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceId, string deviceName);
///
/// Used to report that playback has ended for an item
@@ -147,10 +150,11 @@ namespace MediaBrowser.Controller.Library
/// The item.
/// The position ticks.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// Task.
///
- Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName);
+ Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceId, string deviceName);
///
/// Saves user data for an item
diff --git a/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs b/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs
index b61ea99fa6..a70dddaa65 100644
--- a/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs
+++ b/MediaBrowser.Model/Connectivity/ClientConnectionInfo.cs
@@ -51,5 +51,12 @@ namespace MediaBrowser.Model.Connectivity
/// The now playing position ticks.
[ProtoMember(6)]
public long? NowPlayingPositionTicks { get; set; }
+
+ ///
+ /// Gets or sets the device id.
+ ///
+ /// The device id.
+ [ProtoMember(7)]
+ public string DeviceId { get; set; }
}
}
diff --git a/MediaBrowser.Model/Connectivity/ClientType.cs b/MediaBrowser.Model/Connectivity/ClientType.cs
index 7e837ed0e9..3ae3ded21a 100644
--- a/MediaBrowser.Model/Connectivity/ClientType.cs
+++ b/MediaBrowser.Model/Connectivity/ClientType.cs
@@ -17,6 +17,9 @@
/// The dashboard
///
Dashboard,
+ ///
+ /// The dlna
+ ///
Dlna,
///
/// The ios
diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs
index 3b320a0110..804a6b3990 100644
--- a/MediaBrowser.Model/Querying/ItemQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemQuery.cs
@@ -122,5 +122,11 @@ namespace MediaBrowser.Model.Querying
///
/// The image types.
public ImageType[] ImageTypes { get; set; }
+
+ ///
+ /// Gets or sets the ids, which are specific items to retrieve
+ ///
+ /// The ids.
+ public string[] Ids { get; set; }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 8928ed238e..01a745e95c 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -62,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Library
}
}
}
-
+
///
/// Gets all connections.
///
@@ -71,7 +71,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
get { return _activeConnections.Where(c => GetUserById(c.UserId) != null).OrderByDescending(c => c.LastActivityDate); }
}
-
+
///
/// Gets the active connections.
///
@@ -172,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.Library
return Users.FirstOrDefault(u => u.Id == id);
}
-
+
///
/// Authenticates a User and returns a result indicating whether or not it succeeded
///
@@ -222,10 +222,11 @@ namespace MediaBrowser.Server.Implementations.Library
///
/// The user.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// Task.
/// user
- public Task LogUserActivity(User user, ClientType clientType, string deviceName)
+ public Task LogUserActivity(User user, ClientType clientType, string deviceId, string deviceName)
{
if (user == null)
{
@@ -236,7 +237,7 @@ namespace MediaBrowser.Server.Implementations.Library
user.LastActivityDate = activityDate;
- LogConnection(user.Id, clientType, deviceName, activityDate);
+ LogConnection(user.Id, clientType, deviceId, deviceName, activityDate);
// Save this directly. No need to fire off all the events for this.
return Kernel.UserRepository.SaveUser(user, CancellationToken.None);
@@ -247,15 +248,17 @@ namespace MediaBrowser.Server.Implementations.Library
///
/// The user.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// The item.
/// The current position ticks.
- private void UpdateNowPlayingItemId(User user, ClientType clientType, string deviceName, BaseItem item, long? currentPositionTicks = null)
+ private void UpdateNowPlayingItemId(User user, ClientType clientType, string deviceId, string deviceName, BaseItem item, long? currentPositionTicks = null)
{
- var conn = GetConnection(user.Id, clientType, deviceName);
+ var conn = GetConnection(user.Id, clientType, deviceId, deviceName);
conn.NowPlayingPositionTicks = currentPositionTicks;
conn.NowPlayingItem = DtoBuilder.GetBaseItemInfo(item);
+ conn.LastActivityDate = DateTime.UtcNow;
}
///
@@ -263,11 +266,12 @@ namespace MediaBrowser.Server.Implementations.Library
///
/// The user.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// The item.
- private void RemoveNowPlayingItemId(User user, ClientType clientType, string deviceName, BaseItem item)
+ private void RemoveNowPlayingItemId(User user, ClientType clientType, string deviceId, string deviceName, BaseItem item)
{
- var conn = GetConnection(user.Id, clientType, deviceName);
+ var conn = GetConnection(user.Id, clientType, deviceId, deviceName);
if (conn.NowPlayingItem != null && conn.NowPlayingItem.Id.Equals(item.Id.ToString()))
{
@@ -281,11 +285,12 @@ namespace MediaBrowser.Server.Implementations.Library
///
/// The user id.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// The last activity date.
- private void LogConnection(Guid userId, ClientType clientType, string deviceName, DateTime lastActivityDate)
+ private void LogConnection(Guid userId, ClientType clientType, string deviceId, string deviceName, DateTime lastActivityDate)
{
- GetConnection(userId, clientType, deviceName).LastActivityDate = lastActivityDate;
+ GetConnection(userId, clientType, deviceId, deviceName).LastActivityDate = lastActivityDate;
}
///
@@ -293,11 +298,12 @@ namespace MediaBrowser.Server.Implementations.Library
///
/// The user id.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// ClientConnectionInfo.
- private ClientConnectionInfo GetConnection(Guid userId, ClientType clientType, string deviceName)
+ private ClientConnectionInfo GetConnection(Guid userId, ClientType clientType, string deviceId, string deviceName)
{
- var conn = _activeConnections.FirstOrDefault(c => c.UserId == userId && c.ClientType == clientType && string.Equals(deviceName, c.DeviceName, StringComparison.OrdinalIgnoreCase));
+ var conn = _activeConnections.FirstOrDefault(c => c.UserId == userId && c.ClientType == clientType && string.Equals(deviceId, c.DeviceId));
if (conn == null)
{
@@ -305,7 +311,8 @@ namespace MediaBrowser.Server.Implementations.Library
{
UserId = userId,
ClientType = clientType,
- DeviceName = deviceName
+ DeviceName = deviceName,
+ DeviceId = deviceId
};
_activeConnections.Add(conn);
@@ -524,9 +531,10 @@ namespace MediaBrowser.Server.Implementations.Library
/// The user.
/// The item.
/// Type of the client.
+ /// The device id.
/// Name of the device.
///
- public void OnPlaybackStart(User user, BaseItem item, ClientType clientType, string deviceName)
+ public void OnPlaybackStart(User user, BaseItem item, ClientType clientType, string deviceId, string deviceName)
{
if (user == null)
{
@@ -537,7 +545,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException();
}
- UpdateNowPlayingItemId(user, clientType, deviceName, item);
+ UpdateNowPlayingItemId(user, clientType, deviceId, deviceName, item);
// Nothing to save here
// Fire events to inform plugins
@@ -555,10 +563,11 @@ namespace MediaBrowser.Server.Implementations.Library
/// The item.
/// The position ticks.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// Task.
///
- public async Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName)
+ public async Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceId, string deviceName)
{
if (user == null)
{
@@ -569,7 +578,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException();
}
- UpdateNowPlayingItemId(user, clientType, deviceName, item, positionTicks);
+ UpdateNowPlayingItemId(user, clientType, deviceId, deviceName, item, positionTicks);
if (positionTicks.HasValue)
{
@@ -594,10 +603,11 @@ namespace MediaBrowser.Server.Implementations.Library
/// The item.
/// The position ticks.
/// Type of the client.
+ /// The device id.
/// Name of the device.
/// Task.
///
- public async Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName)
+ public async Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceId, string deviceName)
{
if (user == null)
{
@@ -608,7 +618,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException();
}
- RemoveNowPlayingItemId(user, clientType, deviceName, item);
+ RemoveNowPlayingItemId(user, clientType, deviceId, deviceName, item);
var data = item.GetUserData(user, true);
diff --git a/MediaBrowser.WebDashboard/ApiClient.js b/MediaBrowser.WebDashboard/ApiClient.js
index 4081c31e2e..e7025c8901 100644
--- a/MediaBrowser.WebDashboard/ApiClient.js
+++ b/MediaBrowser.WebDashboard/ApiClient.js
@@ -13,6 +13,8 @@ var ApiClient = {
serverPortNumber: 8096,
+ currentUserId: null,
+
/**
* Detects the hostname and port of MB server based on the current url
*/
@@ -36,14 +38,12 @@ var ApiClient = {
throw new Error("Url name cannot be empty");
}
- params = params || {};
-
var url = ApiClient.serverProtocol + "//" + ApiClient.serverHostName + ":" + ApiClient.serverPortNumber + "/mediabrowser/" + name;
if (params) {
url += "?" + $.param(params);
-
}
+
return url;
},
@@ -76,6 +76,10 @@ var ApiClient = {
return "Web Browser";
},
+
+ getDeviceId: function() {
+ return SHA1(navigator.userAgent + (navigator.cpuClass || ""));
+ },
/**
* Creates a custom api url based on a handler name and query string parameters
@@ -89,16 +93,14 @@ var ApiClient = {
}
params = params || {};
- params.client = "Dashboard";
- params.device = ApiClient.getDeviceName();
params.format = "json";
var url = ApiClient.serverProtocol + "//" + ApiClient.serverHostName + ":" + ApiClient.serverPortNumber + "/mediabrowser/" + name;
if (params) {
url += "?" + $.param(params);
-
}
+
return url;
},
@@ -1063,7 +1065,7 @@ var ApiClient = {
var postData = {
password: SHA1(password || "")
};
-
+
return $.ajax({
type: "POST",
url: url,
@@ -1380,3 +1382,12 @@ var ApiClient = {
// Do this initially. The consumer can always override later
ApiClient.inferServerFromUrl();
+
+$(document).ajaxSend(function (event, jqXHR) {
+
+ if (ApiClient.currentUserId) {
+
+ var auth = 'MediaBrowser UserId="' + ApiClient.currentUserId + '", Client="Dashboard", Device="' + ApiClient.getDeviceName() + '", DeviceId="' + ApiClient.getDeviceName() + '"';
+ jqXHR.setRequestHeader("Authorization", auth);
+ }
+});
\ No newline at end of file
diff --git a/MediaBrowser.WebDashboard/Html/scripts/site.js b/MediaBrowser.WebDashboard/Html/scripts/site.js
index c3c842e7cf..47f0c85085 100644
--- a/MediaBrowser.WebDashboard/Html/scripts/site.js
+++ b/MediaBrowser.WebDashboard/Html/scripts/site.js
@@ -81,12 +81,14 @@ var Dashboard = {
setCurrentUser: function (userId) {
localStorage.setItem("userId", userId);
+ ApiClient.currentUserId = userId;
Dashboard.getUserPromise = null;
},
logout: function () {
localStorage.removeItem("userId");
Dashboard.getUserPromise = null;
+ ApiClient.currentUserId = null;
window.location = "login.html";
},
@@ -1113,6 +1115,13 @@ var Dashboard = {
tag: item.PrimaryImageTag,
type: "Primary"
});
+
+ if (!item.Id || data.icon.indexOf("undefined") != -1) {
+ alert("bad image url: " + JSON.stringify(item));
+ console.log("bad image url: " + JSON.stringify(item));
+
+ continue;
+ }
}
WebNotifications.show(data);
@@ -1200,9 +1209,11 @@ $(document).on('pagebeforeshow', ".page", function () {
}).on('pageinit', ".page", function () {
var page = $(this);
- var hasLogin = Dashboard.getCurrentUserId();
+
+ var userId = Dashboard.getCurrentUserId();
+ ApiClient.currentUserId = userId;
- if (!hasLogin) {
+ if (!userId) {
if (this.id !== "loginPage" && !page.hasClass('wizardPage')) {
diff --git a/MediaBrowser.sln b/MediaBrowser.sln
index 6cb9900552..40460701c8 100644
--- a/MediaBrowser.sln
+++ b/MediaBrowser.sln
@@ -221,4 +221,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(Performance) = preSolution
+ HasPerformanceSessions = true
+ EndGlobalSection
EndGlobal
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 8986333f07..a2a4f88717 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.47
+ 3.0.48
MediaBrowser.Common.Internal
Luke
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains common components shared by Media Browser Theatre and Media Browser Server. Not intended for plugin developer consumption.
Copyright © Media Browser 2013
-
+
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 847ced431a..c3ef3537ba 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.47
+ 3.0.48
MediaBrowser.Common
Media Browser Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 46fcd708ef..7e59d6dab3 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.47
+ 3.0.48
Media Browser.Server.Core
Media Browser Team
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains core components required to build plugins for Media Browser Server.
Copyright © Media Browser 2013
-
+