mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-06-03 22:38:30 +01:00
Update to 3.5.2 and .net core 2.1
This commit is contained in:
@@ -112,7 +112,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
_appHost.HasPendingRestartChanged -= _appHost_HasPendingRestartChanged;
|
||||
|
||||
DisposeTimer();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void DisposeTimer()
|
||||
|
||||
@@ -26,9 +26,10 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
private readonly IDeviceDiscovery _deviceDiscovery;
|
||||
|
||||
private ITimer _timer;
|
||||
private bool _isStarted;
|
||||
private readonly ITimerFactory _timerFactory;
|
||||
|
||||
private NatManager _natManager;
|
||||
|
||||
public ExternalPortForwarding(ILogManager logmanager, IServerApplicationHost appHost, IServerConfigurationManager config, IDeviceDiscovery deviceDiscovery, IHttpClient httpClient, ITimerFactory timerFactory)
|
||||
{
|
||||
_logger = logmanager.GetLogger("PortMapper");
|
||||
@@ -37,6 +38,12 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
_deviceDiscovery = deviceDiscovery;
|
||||
_httpClient = httpClient;
|
||||
_timerFactory = timerFactory;
|
||||
_config.ConfigurationUpdated += _config_ConfigurationUpdated1;
|
||||
}
|
||||
|
||||
private void _config_ConfigurationUpdated1(object sender, EventArgs e)
|
||||
{
|
||||
_config_ConfigurationUpdated(sender, e);
|
||||
}
|
||||
|
||||
private string _lastConfigIdentifier;
|
||||
@@ -49,8 +56,8 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
values.Add(config.PublicPort.ToString(CultureInfo.InvariantCulture));
|
||||
values.Add(_appHost.HttpPort.ToString(CultureInfo.InvariantCulture));
|
||||
values.Add(_appHost.HttpsPort.ToString(CultureInfo.InvariantCulture));
|
||||
values.Add((config.EnableHttps || config.RequireHttps).ToString());
|
||||
values.Add(_appHost.EnableHttps.ToString());
|
||||
values.Add((config.EnableRemoteAccess).ToString());
|
||||
|
||||
return string.Join("|", values.ToArray(values.Count));
|
||||
}
|
||||
@@ -59,10 +66,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
if (!string.Equals(_lastConfigIdentifier, GetConfigIdentifier(), StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (_isStarted)
|
||||
{
|
||||
DisposeNat();
|
||||
}
|
||||
DisposeNat();
|
||||
|
||||
Run();
|
||||
}
|
||||
@@ -70,10 +74,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
public void Run()
|
||||
{
|
||||
NatUtility.Logger = _logger;
|
||||
NatUtility.HttpClient = _httpClient;
|
||||
|
||||
if (_config.Configuration.EnableUPnP)
|
||||
if (_config.Configuration.EnableUPnP && _config.Configuration.EnableRemoteAccess)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
@@ -85,26 +86,18 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
private void Start()
|
||||
{
|
||||
_logger.Debug("Starting NAT discovery");
|
||||
NatUtility.EnabledProtocols = new List<NatProtocol>
|
||||
if (_natManager == null)
|
||||
{
|
||||
NatProtocol.Pmp
|
||||
};
|
||||
NatUtility.DeviceFound += NatUtility_DeviceFound;
|
||||
|
||||
// Mono.Nat does never rise this event. The event is there however it is useless.
|
||||
// You could remove it with no risk.
|
||||
NatUtility.DeviceLost += NatUtility_DeviceLost;
|
||||
|
||||
|
||||
NatUtility.StartDiscovery();
|
||||
_natManager = new NatManager(_logger, _httpClient);
|
||||
_natManager.DeviceFound += NatUtility_DeviceFound;
|
||||
_natManager.StartDiscovery();
|
||||
}
|
||||
|
||||
_timer = _timerFactory.Create(ClearCreatedRules, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10));
|
||||
|
||||
_deviceDiscovery.DeviceDiscovered += _deviceDiscovery_DeviceDiscovered;
|
||||
|
||||
_lastConfigIdentifier = GetConfigIdentifier();
|
||||
|
||||
_isStarted = true;
|
||||
}
|
||||
|
||||
private async void _deviceDiscovery_DeviceDiscovered(object sender, GenericEventArgs<UpnpDeviceInfo> e)
|
||||
@@ -182,8 +175,17 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Debug("Calling Nat.Handle on " + identifier);
|
||||
NatUtility.Handle(localAddress, info, endpoint, NatProtocol.Upnp);
|
||||
// This should never happen, but the Handle method will throw ArgumentNullException if it does
|
||||
if (localAddress == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var natManager = _natManager;
|
||||
if (natManager != null)
|
||||
{
|
||||
await natManager.Handle(localAddress, info, endpoint, NatProtocol.Upnp).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,19 +211,11 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
try
|
||||
{
|
||||
var device = e.Device;
|
||||
_logger.Debug("NAT device found: {0}", device.LocalAddress.ToString());
|
||||
|
||||
CreateRules(device);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// I think it could be a good idea to log the exception because
|
||||
// you are using permanent portmapping here (never expire) and that means that next time
|
||||
// CreatePortMap is invoked it can fails with a 718-ConflictInMappingEntry or not. That depends
|
||||
// on the router's upnp implementation (specs says it should fail however some routers don't do it)
|
||||
// It also can fail with others like 727-ExternalPortOnlySupportsWildcard, 728-NoPortMapsAvailable
|
||||
// and those errors (upnp errors) could be useful for diagnosting.
|
||||
|
||||
// Commenting out because users are reporting problems out of our control
|
||||
//_logger.ErrorException("Error creating port forwarding rules", ex);
|
||||
}
|
||||
@@ -238,14 +232,15 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
// On some systems the device discovered event seems to fire repeatedly
|
||||
// This check will help ensure we're not trying to port map the same device over and over
|
||||
var address = device.LocalAddress;
|
||||
|
||||
var address = device.LocalAddress.ToString();
|
||||
var addressString = address.ToString();
|
||||
|
||||
lock (_createdRules)
|
||||
{
|
||||
if (!_createdRules.Contains(address))
|
||||
if (!_createdRules.Contains(addressString))
|
||||
{
|
||||
_createdRules.Add(address);
|
||||
_createdRules.Add(addressString);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -253,41 +248,32 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
}
|
||||
}
|
||||
|
||||
var success = await CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort).ConfigureAwait(false);
|
||||
|
||||
if (success)
|
||||
{
|
||||
await CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> CreatePortMap(INatDevice device, int privatePort, int publicPort)
|
||||
{
|
||||
_logger.Debug("Creating port map on port {0}", privatePort);
|
||||
|
||||
try
|
||||
{
|
||||
await device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort)
|
||||
{
|
||||
Description = _appHost.Name
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
return true;
|
||||
await CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Error("Error creating port map: " + ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
return false;
|
||||
try
|
||||
{
|
||||
await CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// As I said before, this method will be never invoked. You can remove it.
|
||||
void NatUtility_DeviceLost(object sender, DeviceEventArgs e)
|
||||
private Task CreatePortMap(INatDevice device, int privatePort, int publicPort)
|
||||
{
|
||||
var device = e.Device;
|
||||
_logger.Debug("NAT device lost: {0}", device.LocalAddress.ToString());
|
||||
_logger.Debug("Creating port map on local port {0} to public port {1} with device {2}", privatePort, publicPort, device.LocalAddress.ToString());
|
||||
|
||||
return device.CreatePortMap(new Mapping(Protocol.Tcp, privatePort, publicPort)
|
||||
{
|
||||
Description = _appHost.Name
|
||||
});
|
||||
}
|
||||
|
||||
private bool _disposed = false;
|
||||
@@ -295,7 +281,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
_disposed = true;
|
||||
DisposeNat();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private void DisposeNat()
|
||||
@@ -310,27 +295,24 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
_deviceDiscovery.DeviceDiscovered -= _deviceDiscovery_DeviceDiscovered;
|
||||
|
||||
try
|
||||
var natManager = _natManager;
|
||||
|
||||
if (natManager != null)
|
||||
{
|
||||
// This is not a significant improvement
|
||||
NatUtility.StopDiscovery();
|
||||
NatUtility.DeviceFound -= NatUtility_DeviceFound;
|
||||
NatUtility.DeviceLost -= NatUtility_DeviceLost;
|
||||
}
|
||||
// Statements in try-block will no fail because StopDiscovery is a one-line
|
||||
// method that was no chances to fail.
|
||||
// public static void StopDiscovery ()
|
||||
// {
|
||||
// searching.Reset();
|
||||
// }
|
||||
// IMO you could remove the catch-block
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error stopping NAT Discovery", ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isStarted = false;
|
||||
_natManager = null;
|
||||
|
||||
using (natManager)
|
||||
{
|
||||
try
|
||||
{
|
||||
natManager.StopDiscovery();
|
||||
natManager.DeviceFound -= NatUtility_DeviceFound;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error stopping NAT Discovery", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
_timer.Dispose();
|
||||
_timer = null;
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// <summary>
|
||||
/// The library update duration
|
||||
/// </summary>
|
||||
private const int LibraryUpdateDuration = 5000;
|
||||
private const int LibraryUpdateDuration = 30000;
|
||||
|
||||
private readonly IProviderManager _providerManager;
|
||||
|
||||
@@ -315,41 +315,39 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
private async void SendChangeNotifications(List<BaseItem> itemsAdded, List<BaseItem> itemsUpdated, List<BaseItem> itemsRemoved, List<Folder> foldersAddedTo, List<Folder> foldersRemovedFrom, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (var user in _userManager.Users.ToList())
|
||||
var userIds = _sessionManager.Sessions
|
||||
.Select(i => i.UserId)
|
||||
.Where(i => !i.Equals(Guid.Empty))
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
|
||||
foreach (var userId in userIds)
|
||||
{
|
||||
var id = user.Id;
|
||||
var userSessions = _sessionManager.Sessions
|
||||
.Where(u => u.UserId.HasValue && u.UserId.Value == id && u.SessionController != null && u.IsActive)
|
||||
.ToList();
|
||||
LibraryUpdateInfo info;
|
||||
|
||||
if (userSessions.Count > 0)
|
||||
try
|
||||
{
|
||||
LibraryUpdateInfo info;
|
||||
|
||||
try
|
||||
{
|
||||
info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo,
|
||||
foldersRemovedFrom, id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error in GetLibraryUpdateInfo", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var userSession in userSessions)
|
||||
{
|
||||
try
|
||||
{
|
||||
await userSession.SessionController.SendLibraryUpdateInfo(info, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error sending LibraryChanged message", ex);
|
||||
}
|
||||
}
|
||||
info = GetLibraryUpdateInfo(itemsAdded, itemsUpdated, itemsRemoved, foldersAddedTo, foldersRemovedFrom, userId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error in GetLibraryUpdateInfo", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.IsEmpty)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await _sessionManager.SendMessageToUserSessions(new List<Guid> { userId }, "LibraryChanged", info, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error sending LibraryChanged message", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +389,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
private bool FilterItem(BaseItem item)
|
||||
{
|
||||
if (!item.IsFolder && item.LocationType == LocationType.Virtual)
|
||||
if (!item.IsFolder && !item.HasPathProtocol)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -440,7 +438,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
// If the physical root changed, return the user root
|
||||
if (item is AggregateFolder)
|
||||
{
|
||||
return new[] { user.RootFolder as T };
|
||||
return new[] { _libraryManager.GetUserRootFolder() as T };
|
||||
}
|
||||
|
||||
// Return it only if it's in the user's library
|
||||
@@ -458,7 +456,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -474,10 +471,14 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
LibraryUpdateTimer.Dispose();
|
||||
LibraryUpdateTimer = null;
|
||||
}
|
||||
|
||||
|
||||
_libraryManager.ItemAdded -= libraryManager_ItemAdded;
|
||||
_libraryManager.ItemUpdated -= libraryManager_ItemUpdated;
|
||||
_libraryManager.ItemRemoved -= libraryManager_ItemRemoved;
|
||||
|
||||
_providerManager.RefreshCompleted -= _providerManager_RefreshCompleted;
|
||||
_providerManager.RefreshStarted -= _providerManager_RefreshStarted;
|
||||
_providerManager.RefreshProgress -= _providerManager_RefreshProgress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
using MediaBrowser.Common.Security;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Threading;
|
||||
|
||||
namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
/// <summary>
|
||||
/// Class LoadRegistrations
|
||||
/// </summary>
|
||||
public class LoadRegistrations : IServerEntryPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// The _security manager
|
||||
/// </summary>
|
||||
private readonly ISecurityManager _securityManager;
|
||||
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private ITimer _timer;
|
||||
private readonly ITimerFactory _timerFactory;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LoadRegistrations" /> class.
|
||||
/// </summary>
|
||||
/// <param name="securityManager">The security manager.</param>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
public LoadRegistrations(ISecurityManager securityManager, ILogManager logManager, ITimerFactory timerFactory)
|
||||
{
|
||||
_securityManager = securityManager;
|
||||
_timerFactory = timerFactory;
|
||||
|
||||
_logger = logManager.GetLogger("Registration Loader");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs this instance.
|
||||
/// </summary>
|
||||
public void Run()
|
||||
{
|
||||
_timer = _timerFactory.Create(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(12));
|
||||
}
|
||||
|
||||
private async Task LoadAllRegistrations()
|
||||
{
|
||||
try
|
||||
{
|
||||
await _securityManager.LoadAllRegistrationInfo().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error loading registration info", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_timer != null)
|
||||
{
|
||||
_timer.Dispose();
|
||||
_timer = null;
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,11 +54,15 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
private async void SendMessage(string name, TimerEventInfo info)
|
||||
{
|
||||
var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id.ToString("N")).ToList();
|
||||
var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id).ToList();
|
||||
|
||||
try
|
||||
{
|
||||
await _sessionManager.SendMessageToUserSessions<TimerEventInfo>(users, name, info, CancellationToken.None);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -72,7 +76,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
_liveTvManager.SeriesTimerCancelled -= _liveTvManager_SeriesTimerCancelled;
|
||||
_liveTvManager.TimerCreated -= _liveTvManager_TimerCreated;
|
||||
_liveTvManager.SeriesTimerCreated -= _liveTvManager_SeriesTimerCreated;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// </summary>
|
||||
public class ServerEventNotifier : IServerEntryPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// The _server manager
|
||||
/// </summary>
|
||||
private readonly IServerManager _serverManager;
|
||||
|
||||
/// <summary>
|
||||
/// The _user manager
|
||||
/// </summary>
|
||||
@@ -47,23 +42,21 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
private readonly ITaskManager _taskManager;
|
||||
|
||||
private readonly ISessionManager _sessionManager;
|
||||
private readonly ISyncManager _syncManager;
|
||||
|
||||
public ServerEventNotifier(IServerManager serverManager, IServerApplicationHost appHost, IUserManager userManager, IInstallationManager installationManager, ITaskManager taskManager, ISessionManager sessionManager, ISyncManager syncManager)
|
||||
public ServerEventNotifier(IServerApplicationHost appHost, IUserManager userManager, IInstallationManager installationManager, ITaskManager taskManager, ISessionManager sessionManager)
|
||||
{
|
||||
_serverManager = serverManager;
|
||||
_userManager = userManager;
|
||||
_installationManager = installationManager;
|
||||
_appHost = appHost;
|
||||
_taskManager = taskManager;
|
||||
_sessionManager = sessionManager;
|
||||
_syncManager = syncManager;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
_userManager.UserDeleted += userManager_UserDeleted;
|
||||
_userManager.UserUpdated += userManager_UserUpdated;
|
||||
_userManager.UserPolicyUpdated += _userManager_UserPolicyUpdated;
|
||||
_userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated;
|
||||
|
||||
_appHost.HasPendingRestartChanged += kernel_HasPendingRestartChanged;
|
||||
@@ -75,43 +68,31 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
_installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed;
|
||||
|
||||
_taskManager.TaskCompleted += _taskManager_TaskCompleted;
|
||||
_syncManager.SyncJobCreated += _syncManager_SyncJobCreated;
|
||||
_syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled;
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobCancelled(object sender, GenericEventArgs<SyncJob> e)
|
||||
{
|
||||
_sessionManager.SendMessageToUserDeviceSessions(e.Argument.TargetId, "SyncJobCancelled", e.Argument, CancellationToken.None);
|
||||
}
|
||||
|
||||
void _syncManager_SyncJobCreated(object sender, GenericEventArgs<SyncJobCreationResult> e)
|
||||
{
|
||||
_sessionManager.SendMessageToUserDeviceSessions(e.Argument.Job.TargetId, "SyncJobCreated", e.Argument, CancellationToken.None);
|
||||
}
|
||||
|
||||
void _installationManager_PackageInstalling(object sender, InstallationEventArgs e)
|
||||
{
|
||||
_serverManager.SendWebSocketMessage("PackageInstalling", e.InstallationInfo);
|
||||
SendMessageToAdminSessions("PackageInstalling", e.InstallationInfo);
|
||||
}
|
||||
|
||||
void _installationManager_PackageInstallationCancelled(object sender, InstallationEventArgs e)
|
||||
{
|
||||
_serverManager.SendWebSocketMessage("PackageInstallationCancelled", e.InstallationInfo);
|
||||
SendMessageToAdminSessions("PackageInstallationCancelled", e.InstallationInfo);
|
||||
}
|
||||
|
||||
void _installationManager_PackageInstallationCompleted(object sender, InstallationEventArgs e)
|
||||
{
|
||||
_serverManager.SendWebSocketMessage("PackageInstallationCompleted", e.InstallationInfo);
|
||||
SendMessageToAdminSessions("PackageInstallationCompleted", e.InstallationInfo);
|
||||
}
|
||||
|
||||
void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e)
|
||||
{
|
||||
_serverManager.SendWebSocketMessage("PackageInstallationFailed", e.InstallationInfo);
|
||||
SendMessageToAdminSessions("PackageInstallationFailed", e.InstallationInfo);
|
||||
}
|
||||
|
||||
void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e)
|
||||
{
|
||||
_serverManager.SendWebSocketMessage("ScheduledTaskEnded", e.Result);
|
||||
SendMessageToAdminSessions("ScheduledTaskEnded", e.Result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -121,7 +102,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// <param name="e">The e.</param>
|
||||
void InstallationManager_PluginUninstalled(object sender, GenericEventArgs<IPlugin> e)
|
||||
{
|
||||
_serverManager.SendWebSocketMessage("PluginUninstalled", e.Argument.GetPluginInfo());
|
||||
SendMessageToAdminSessions("PluginUninstalled", e.Argument.GetPluginInfo());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -156,6 +137,13 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N"));
|
||||
}
|
||||
|
||||
void _userManager_UserPolicyUpdated(object sender, GenericEventArgs<User> e)
|
||||
{
|
||||
var dto = _userManager.GetUserDto(e.Argument);
|
||||
|
||||
SendMessageToUserSession(e.Argument, "UserPolicyUpdated", dto);
|
||||
}
|
||||
|
||||
void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs<User> e)
|
||||
{
|
||||
var dto = _userManager.GetUserDto(e.Argument);
|
||||
@@ -163,9 +151,36 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
SendMessageToUserSession(e.Argument, "UserConfigurationUpdated", dto);
|
||||
}
|
||||
|
||||
private async void SendMessageToAdminSessions<T>(string name, T data)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _sessionManager.SendMessageToAdminSessions(name, data, CancellationToken.None);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Logger.ErrorException("Error sending message", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async void SendMessageToUserSession<T>(User user, string name, T data)
|
||||
{
|
||||
await _sessionManager.SendMessageToUserSessions(new List<string> { user.Id.ToString("N") }, name, data, CancellationToken.None);
|
||||
try
|
||||
{
|
||||
await _sessionManager.SendMessageToUserSessions(new List<Guid> { user.Id }, name, data, CancellationToken.None);
|
||||
}
|
||||
catch (ObjectDisposedException)
|
||||
{
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
//Logger.ErrorException("Error sending message", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -174,7 +189,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -187,6 +201,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
{
|
||||
_userManager.UserDeleted -= userManager_UserDeleted;
|
||||
_userManager.UserUpdated -= userManager_UserUpdated;
|
||||
_userManager.UserPolicyUpdated -= _userManager_UserPolicyUpdated;
|
||||
_userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated;
|
||||
|
||||
_installationManager.PluginUninstalled -= InstallationManager_PluginUninstalled;
|
||||
@@ -196,8 +211,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
_installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed;
|
||||
|
||||
_appHost.HasPendingRestartChanged -= kernel_HasPendingRestartChanged;
|
||||
_syncManager.SyncJobCreated -= _syncManager_SyncJobCreated;
|
||||
_syncManager.SyncJobCancelled -= _syncManager_SyncJobCancelled;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Emby.Server.Implementations.Browser;
|
||||
using Emby.Server.Implementations.Browser;
|
||||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
using MediaBrowser.Model.Logging;
|
||||
@@ -40,17 +39,17 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
return;
|
||||
}
|
||||
|
||||
if (_appHost.IsFirstRun)
|
||||
if (!_config.Configuration.IsStartupWizardCompleted)
|
||||
{
|
||||
BrowserLauncher.OpenDashboardPage("wizardstart.html", _appHost);
|
||||
BrowserLauncher.OpenWebApp(_appHost);
|
||||
}
|
||||
else if (_config.Configuration.IsStartupWizardCompleted && _config.Configuration.AutoRunWebApp)
|
||||
else if (_config.Configuration.AutoRunWebApp)
|
||||
{
|
||||
var options = ((ApplicationHost)_appHost).StartupOptions;
|
||||
|
||||
if (!options.ContainsOption("-noautorunwebapp"))
|
||||
{
|
||||
BrowserLauncher.OpenDashboardPage("index.html", _appHost);
|
||||
BrowserLauncher.OpenWebApp(_appHost);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +59,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
public void Dispose()
|
||||
{
|
||||
_systemEvents.SystemShutdown -= _systemEvents_SystemShutdown;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,9 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
/// </summary>
|
||||
public void Run()
|
||||
{
|
||||
// ToDo: Fix This
|
||||
return;
|
||||
|
||||
var udpServer = new UdpServer(_logger, _appHost, _json, _socketFactory);
|
||||
|
||||
try
|
||||
@@ -65,7 +68,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Plugins;
|
||||
@@ -61,17 +60,29 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
var key = string.Join("_", keys.ToArray(keys.Count)).GetMD5();
|
||||
|
||||
_apps.GetOrAdd(key, guid => GetNewClientInfo(session));
|
||||
ClientInfo info;
|
||||
if (!_apps.TryGetValue(key, out info))
|
||||
{
|
||||
info = new ClientInfo
|
||||
{
|
||||
AppName = session.Client,
|
||||
AppVersion = session.ApplicationVersion,
|
||||
DeviceName = session.DeviceName,
|
||||
DeviceId = session.DeviceId
|
||||
};
|
||||
|
||||
_apps[key] = info;
|
||||
|
||||
if (_config.Configuration.EnableAnonymousUsageReporting)
|
||||
{
|
||||
Task.Run(() => ReportNewSession(info));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void ReportNewSession(ClientInfo client)
|
||||
private async Task ReportNewSession(ClientInfo client)
|
||||
{
|
||||
if (!_config.Configuration.EnableAnonymousUsageReporting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
await new UsageReporter(_applicationHost, _httpClient, _logger)
|
||||
@@ -80,25 +91,10 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error sending anonymous usage statistics.", ex);
|
||||
//_logger.ErrorException("Error sending anonymous usage statistics.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private ClientInfo GetNewClientInfo(SessionInfo session)
|
||||
{
|
||||
var info = new ClientInfo
|
||||
{
|
||||
AppName = session.Client,
|
||||
AppVersion = session.ApplicationVersion,
|
||||
DeviceName = session.DeviceName,
|
||||
DeviceId = session.DeviceId
|
||||
};
|
||||
|
||||
ReportNewSession(info);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public async void Run()
|
||||
{
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
@@ -123,14 +119,13 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error sending anonymous usage statistics.", ex);
|
||||
//_logger.ErrorException("Error sending anonymous usage statistics.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_sessionManager.SessionStarted -= _sessionManager_SessionStarted;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
|
||||
public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(app.DeviceId))
|
||||
if (string.IsNullOrEmpty(app.DeviceId))
|
||||
{
|
||||
throw new ArgumentException("Client info must have a device Id");
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
private readonly ITimerFactory _timerFactory;
|
||||
private const int UpdateDuration = 500;
|
||||
|
||||
private readonly Dictionary<Guid, List<IHasUserData>> _changedItems = new Dictionary<Guid, List<IHasUserData>>();
|
||||
private readonly Dictionary<Guid, List<BaseItem>> _changedItems = new Dictionary<Guid, List<BaseItem>>();
|
||||
|
||||
public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, ILogger logger, IUserManager userManager, ITimerFactory timerFactory)
|
||||
{
|
||||
@@ -62,22 +62,22 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
UpdateTimer.Change(UpdateDuration, Timeout.Infinite);
|
||||
}
|
||||
|
||||
List<IHasUserData> keys;
|
||||
List<BaseItem> keys;
|
||||
|
||||
if (!_changedItems.TryGetValue(e.UserId, out keys))
|
||||
{
|
||||
keys = new List<IHasUserData>();
|
||||
keys = new List<BaseItem>();
|
||||
_changedItems[e.UserId] = keys;
|
||||
}
|
||||
|
||||
keys.Add(e.Item);
|
||||
|
||||
var baseItem = e.Item as BaseItem;
|
||||
var baseItem = e.Item;
|
||||
|
||||
// Go up one level for indicators
|
||||
if (baseItem != null)
|
||||
{
|
||||
var parent = baseItem.IsOwnedItem ? baseItem.GetOwner() : baseItem.GetParent();
|
||||
var parent = baseItem.GetOwner() ?? baseItem.GetParent();
|
||||
|
||||
if (parent != null)
|
||||
{
|
||||
@@ -105,52 +105,43 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SendNotifications(IEnumerable<KeyValuePair<Guid, List<IHasUserData>>> changes, CancellationToken cancellationToken)
|
||||
private async Task SendNotifications(List<KeyValuePair<Guid, List<BaseItem>>> changes, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (var pair in changes)
|
||||
{
|
||||
var userId = pair.Key;
|
||||
var userSessions = _sessionManager.Sessions
|
||||
.Where(u => u.ContainsUser(userId) && u.SessionController != null && u.IsActive)
|
||||
.ToList();
|
||||
|
||||
if (userSessions.Count > 0)
|
||||
{
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
var dtoList = pair.Value
|
||||
.DistinctBy(i => i.Id)
|
||||
.Select(i =>
|
||||
{
|
||||
var dto = _userDataManager.GetUserDataDto(i, user);
|
||||
dto.ItemId = i.Id.ToString("N");
|
||||
return dto;
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
var info = new UserDataChangeInfo
|
||||
{
|
||||
UserId = userId.ToString("N"),
|
||||
|
||||
UserDataList = dtoList
|
||||
};
|
||||
|
||||
foreach (var userSession in userSessions)
|
||||
{
|
||||
try
|
||||
{
|
||||
await userSession.SessionController.SendUserDataChangeInfo(info, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error sending UserDataChanged message", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await SendNotifications(pair.Key, pair.Value, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
private Task SendNotifications(Guid userId, List<BaseItem> changedItems, CancellationToken cancellationToken)
|
||||
{
|
||||
return _sessionManager.SendMessageToUserSessions(new List<Guid> { userId }, "UserDataChanged", () => GetUserDataChangeInfo(userId, changedItems), cancellationToken);
|
||||
}
|
||||
|
||||
private UserDataChangeInfo GetUserDataChangeInfo(Guid userId, List<BaseItem> changedItems)
|
||||
{
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
var dtoList = changedItems
|
||||
.DistinctBy(i => i.Id)
|
||||
.Select(i =>
|
||||
{
|
||||
var dto = _userDataManager.GetUserDataDto(i, user);
|
||||
dto.ItemId = i.Id.ToString("N");
|
||||
return dto;
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
var userIdString = userId.ToString("N");
|
||||
|
||||
return new UserDataChangeInfo
|
||||
{
|
||||
UserId = userIdString,
|
||||
|
||||
UserDataList = dtoList
|
||||
};
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (UpdateTimer != null)
|
||||
@@ -160,7 +151,6 @@ namespace Emby.Server.Implementations.EntryPoints
|
||||
}
|
||||
|
||||
_userDataManager.UserDataSaved -= _userDataManager_UserDataSaved;
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user