diff options
5 files changed, 107 insertions, 7 deletions
diff --git a/MediaBrowser.Common.Implementations/Security/UsageReporter.cs b/MediaBrowser.Common.Implementations/Security/UsageReporter.cs index e32940be9..7c8127db3 100644 --- a/MediaBrowser.Common.Implementations/Security/UsageReporter.cs +++ b/MediaBrowser.Common.Implementations/Security/UsageReporter.cs @@ -19,7 +19,7 @@ namespace MediaBrowser.Common.Implementations.Security _httpClient = httpClient; } - public Task ReportUsage(CancellationToken cancellationToken) + public Task ReportServerUsage(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -36,5 +36,20 @@ namespace MediaBrowser.Common.Implementations.Security return _httpClient.Post(Constants.Constants.MbAdminUrl + "service/registration/ping", data, cancellationToken); } + + public Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) + { + // TODO: Implement this + // Make sure to handle DeviceVersion being + + return Task.FromResult(true); + } + } + + public class ClientInfo + { + public string AppName { get; set; } + public string AppVersion { get; set; } + public string DeviceVersion { get; set; } } } diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index bc0f8a5d1..d8052b9bf 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -87,6 +87,12 @@ namespace MediaBrowser.Controller.Session public string DeviceName { get; set; } /// <summary> + /// Gets or sets the device version. + /// </summary> + /// <value>The device version.</value> + public string DeviceVersion { get; set; } + + /// <summary> /// Gets or sets the name of the now viewing item. /// </summary> /// <value>The name of the now viewing item.</value> diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs index 3ab47f51b..5f5d5d901 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs @@ -1,9 +1,13 @@ using MediaBrowser.Common; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Implementations.Security; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; using MediaBrowser.Model.Logging; using System; +using System.Collections.Concurrent; +using System.Collections.Generic; using System.Threading; namespace MediaBrowser.Server.Implementations.EntryPoints @@ -17,16 +21,88 @@ namespace MediaBrowser.Server.Implementations.EntryPoints private readonly INetworkManager _networkManager; private readonly IHttpClient _httpClient; private readonly ILogger _logger; + private readonly ISessionManager _sessionManager; private Timer _timer; private readonly TimeSpan _frequency = TimeSpan.FromHours(24); - public UsageEntryPoint(ILogger logger, IApplicationHost applicationHost, INetworkManager networkManager, IHttpClient httpClient) + private const string DefaultDeviceVersion = "Unknown version"; + private readonly ConcurrentDictionary<Guid, ClientInfo> _apps = new ConcurrentDictionary<Guid, ClientInfo>(); + + public UsageEntryPoint(ILogger logger, IApplicationHost applicationHost, INetworkManager networkManager, IHttpClient httpClient, ISessionManager sessionManager) { _logger = logger; _applicationHost = applicationHost; _networkManager = networkManager; _httpClient = httpClient; + _sessionManager = sessionManager; + + _sessionManager.SessionStarted += _sessionManager_SessionStarted; + } + + void _sessionManager_SessionStarted(object sender, SessionEventArgs e) + { + var session = e.SessionInfo; + + if (!string.IsNullOrEmpty(session.Client) && + !string.IsNullOrEmpty(session.DeviceName)) + { + var keys = new List<string> + { + session.Client, + session.DeviceName + }; + + if (!string.IsNullOrEmpty(session.DeviceVersion)) + { + keys.Add(session.DeviceVersion); + } + else + { + keys.Add(DefaultDeviceVersion); + } + + var key = string.Join("_", keys.ToArray()).GetMD5(); + + _apps.GetOrAdd(key, guid => GetNewClientInfo(session)); + } + } + + private async void ReportNewSession(ClientInfo client) + { + try + { + await new UsageReporter(_applicationHost, _networkManager, _httpClient) + .ReportAppUsage(client, CancellationToken.None) + .ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending anonymous usage statistics.", ex); + } + } + + private ClientInfo GetNewClientInfo(SessionInfo session) + { + var info = new ClientInfo + { + AppName = session.Client, + AppVersion = session.ApplicationVersion, + DeviceVersion = session.DeviceVersion + }; + + if (string.IsNullOrEmpty(info.DeviceVersion)) + { + info.DeviceVersion = DefaultDeviceVersion; + } + + // Report usage to remote server, except for web client, since we already have data on that + if (!string.Equals(info.AppName, "Dashboard", StringComparison.OrdinalIgnoreCase)) + { + ReportNewSession(info); + } + + return info; } public void Run() @@ -42,8 +118,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints { try { - await new UsageReporter(_applicationHost, _networkManager, _httpClient).ReportUsage(CancellationToken.None) - .ConfigureAwait(false); + await new UsageReporter(_applicationHost, _networkManager, _httpClient) + .ReportServerUsage(CancellationToken.None) + .ConfigureAwait(false); } catch (Exception ex) { @@ -53,6 +130,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints public void Dispose() { + _sessionManager.SessionStarted -= _sessionManager_SessionStarted; + if (_timer != null) { _timer.Dispose(); diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 290029b41..efc7ebb6a 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -48,9 +48,9 @@ <Reference Include="Alchemy"> <HintPath>..\packages\Alchemy.2.2.1\lib\net40\Alchemy.dll</HintPath> </Reference> - <Reference Include="Mono.Nat, Version=1.2.10.0, Culture=neutral, processorArchitecture=MSIL"> + <Reference Include="Mono.Nat, Version=1.2.13.0, Culture=neutral, processorArchitecture=MSIL"> <SpecificVersion>False</SpecificVersion> - <HintPath>..\packages\Mono.Nat.1.2.10.0\lib\net40\Mono.Nat.dll</HintPath> + <HintPath>..\packages\Mono.Nat.1.2.13.0\lib\net40\Mono.Nat.dll</HintPath> </Reference> <Reference Include="ServiceStack.Api.Swagger"> <HintPath>..\ThirdParty\ServiceStack\ServiceStack.Api.Swagger.dll</HintPath> diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index d2ee5161d..fb04de92f 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Alchemy" version="2.2.1" targetFramework="net45" />
- <package id="Mono.Nat" version="1.2.10.0" targetFramework="net45" />
+ <package id="Mono.Nat" version="1.2.13.0" targetFramework="net45" />
<package id="morelinq" version="1.0.16006" targetFramework="net45" />
<package id="System.Data.SQLite.Core" version="1.0.91.3" targetFramework="net45" />
</packages>
\ No newline at end of file |
