From b76a1abda578b8ff64bad2997b036b0fc43e264f Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Nov 2016 03:14:14 -0400 Subject: move classes to portable server lib --- .../EntryPoints/ActivityLogEntryPoint.cs | 561 --------------------- .../EntryPoints/Notifications/Notifications.cs | 544 -------------------- .../EntryPoints/Notifications/WebSocketNotifier.cs | 54 -- 3 files changed, 1159 deletions(-) delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs deleted file mode 100644 index 51f5f57b3e..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/ActivityLogEntryPoint.cs +++ /dev/null @@ -1,561 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Common.Updates; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Controller.Subtitles; -using MediaBrowser.Model.Activity; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Tasks; -using MediaBrowser.Model.Updates; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using MediaBrowser.Model.Globalization; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - public class ActivityLogEntryPoint : IServerEntryPoint - { - private readonly IInstallationManager _installationManager; - - //private readonly ILogManager _logManager; - //private readonly ILogger _logger; - private readonly ISessionManager _sessionManager; - private readonly ITaskManager _taskManager; - private readonly IActivityManager _activityManager; - private readonly ILocalizationManager _localization; - - private readonly ILibraryManager _libraryManager; - private readonly ISubtitleManager _subManager; - private readonly IUserManager _userManager; - private readonly IServerConfigurationManager _config; - private readonly IServerApplicationHost _appHost; - - public ActivityLogEntryPoint(ISessionManager sessionManager, ITaskManager taskManager, IActivityManager activityManager, ILocalizationManager localization, IInstallationManager installationManager, ILibraryManager libraryManager, ISubtitleManager subManager, IUserManager userManager, IServerConfigurationManager config, IServerApplicationHost appHost) - { - //_logger = _logManager.GetLogger("ActivityLogEntryPoint"); - _sessionManager = sessionManager; - _taskManager = taskManager; - _activityManager = activityManager; - _localization = localization; - _installationManager = installationManager; - _libraryManager = libraryManager; - _subManager = subManager; - _userManager = userManager; - _config = config; - //_logManager = logManager; - _appHost = appHost; - } - - public void Run() - { - //_taskManager.TaskExecuting += _taskManager_TaskExecuting; - //_taskManager.TaskCompleted += _taskManager_TaskCompleted; - - //_installationManager.PluginInstalled += _installationManager_PluginInstalled; - //_installationManager.PluginUninstalled += _installationManager_PluginUninstalled; - //_installationManager.PluginUpdated += _installationManager_PluginUpdated; - - //_libraryManager.ItemAdded += _libraryManager_ItemAdded; - //_libraryManager.ItemRemoved += _libraryManager_ItemRemoved; - - _sessionManager.SessionStarted += _sessionManager_SessionStarted; - _sessionManager.AuthenticationFailed += _sessionManager_AuthenticationFailed; - _sessionManager.AuthenticationSucceeded += _sessionManager_AuthenticationSucceeded; - _sessionManager.SessionEnded += _sessionManager_SessionEnded; - - _sessionManager.PlaybackStart += _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped += _sessionManager_PlaybackStopped; - - //_subManager.SubtitlesDownloaded += _subManager_SubtitlesDownloaded; - _subManager.SubtitleDownloadFailure += _subManager_SubtitleDownloadFailure; - - _userManager.UserCreated += _userManager_UserCreated; - _userManager.UserPasswordChanged += _userManager_UserPasswordChanged; - _userManager.UserDeleted += _userManager_UserDeleted; - _userManager.UserConfigurationUpdated += _userManager_UserConfigurationUpdated; - _userManager.UserLockedOut += _userManager_UserLockedOut; - - //_config.ConfigurationUpdated += _config_ConfigurationUpdated; - //_config.NamedConfigurationUpdated += _config_NamedConfigurationUpdated; - - //_logManager.LoggerLoaded += _logManager_LoggerLoaded; - - _appHost.ApplicationUpdated += _appHost_ApplicationUpdated; - } - - void _userManager_UserLockedOut(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserLockedOutWithName"), e.Argument.Name), - Type = "UserLockedOut", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _subManager_SubtitleDownloadFailure(object sender, SubtitleDownloadFailureEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("SubtitleDownloadFailureForItem"), Notifications.Notifications.GetItemName(e.Item)), - Type = "SubtitleDownloadFailure", - ItemId = e.Item.Id.ToString("N"), - ShortOverview = string.Format(_localization.GetLocalizedString("ProviderValue"), e.Provider), - Overview = LogHelper.GetLogMessage(e.Exception).ToString() - }); - } - - void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - //_logger.Warn("PlaybackStopped reported with null media info."); - return; - } - - if (item.IsThemeMedia) - { - // Don't report theme song or local trailer playback - return; - } - - if (e.Users.Count == 0) - { - return; - } - - var user = e.Users.First(); - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserStoppedPlayingItemWithValues"), user.Name, item.Name), - Type = "PlaybackStopped", - ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName), - UserId = user.Id.ToString("N") - }); - } - - void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - //_logger.Warn("PlaybackStart reported with null media info."); - return; - } - - if (item.IsThemeMedia) - { - // Don't report theme song or local trailer playback - return; - } - - if (e.Users.Count == 0) - { - return; - } - - var user = e.Users.First(); - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserStartedPlayingItemWithValues"), user.Name, item.Name), - Type = "PlaybackStart", - ShortOverview = string.Format(_localization.GetLocalizedString("AppDeviceValues"), e.ClientName, e.DeviceName), - UserId = user.Id.ToString("N") - }); - } - - void _sessionManager_SessionEnded(object sender, SessionEventArgs e) - { - string name; - var session = e.SessionInfo; - - if (string.IsNullOrWhiteSpace(session.UserName)) - { - name = string.Format(_localization.GetLocalizedString("DeviceOfflineWithName"), session.DeviceName); - - // Causing too much spam for now - return; - } - else - { - name = string.Format(_localization.GetLocalizedString("UserOfflineFromDevice"), session.UserName, session.DeviceName); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = name, - Type = "SessionEnded", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint), - UserId = session.UserId.HasValue ? session.UserId.Value.ToString("N") : null - }); - } - - void _sessionManager_AuthenticationSucceeded(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("AuthenticationSucceededWithUserName"), e.Argument.Username), - Type = "AuthenticationSucceeded", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint) - }); - } - - void _sessionManager_AuthenticationFailed(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("FailedLoginAttemptWithUserName"), e.Argument.Username), - Type = "AuthenticationFailed", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), e.Argument.RemoteEndPoint), - Severity = LogSeverity.Error - }); - } - - void _appHost_ApplicationUpdated(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = _localization.GetLocalizedString("MessageApplicationUpdated"), - Type = "ApplicationUpdated", - ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.versionStr), - Overview = e.Argument.description - }); - } - - void _logManager_LoggerLoaded(object sender, EventArgs e) - { - } - - void _config_NamedConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("MessageNamedServerConfigurationUpdatedWithValue"), e.Key), - Type = "NamedConfigurationUpdated" - }); - } - - void _config_ConfigurationUpdated(object sender, EventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = _localization.GetLocalizedString("MessageServerConfigurationUpdated"), - Type = "ServerConfigurationUpdated" - }); - } - - void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserConfigurationUpdatedWithName"), e.Argument.Name), - Type = "UserConfigurationUpdated", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _userManager_UserDeleted(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserDeletedWithName"), e.Argument.Name), - Type = "UserDeleted" - }); - } - - void _userManager_UserPasswordChanged(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserPasswordChangedWithName"), e.Argument.Name), - Type = "UserPasswordChanged", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _userManager_UserCreated(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("UserCreatedWithName"), e.Argument.Name), - Type = "UserCreated", - UserId = e.Argument.Id.ToString("N") - }); - } - - void _subManager_SubtitlesDownloaded(object sender, SubtitleDownloadEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("SubtitlesDownloadedForItem"), Notifications.Notifications.GetItemName(e.Item)), - Type = "SubtitlesDownloaded", - ItemId = e.Item.Id.ToString("N"), - ShortOverview = string.Format(_localization.GetLocalizedString("ProviderValue"), e.Provider) - }); - } - - void _sessionManager_SessionStarted(object sender, SessionEventArgs e) - { - string name; - var session = e.SessionInfo; - - if (string.IsNullOrWhiteSpace(session.UserName)) - { - name = string.Format(_localization.GetLocalizedString("DeviceOnlineWithName"), session.DeviceName); - - // Causing too much spam for now - return; - } - else - { - name = string.Format(_localization.GetLocalizedString("UserOnlineFromDevice"), session.UserName, session.DeviceName); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = name, - Type = "SessionStarted", - ShortOverview = string.Format(_localization.GetLocalizedString("LabelIpAddressValue"), session.RemoteEndPoint), - UserId = session.UserId.HasValue ? session.UserId.Value.ToString("N") : null - }); - } - - void _libraryManager_ItemRemoved(object sender, ItemChangeEventArgs e) - { - if (e.Item.SourceType != SourceType.Library) - { - return; - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ItemRemovedWithName"), Notifications.Notifications.GetItemName(e.Item)), - Type = "ItemRemoved" - }); - } - - void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) - { - if (e.Item.SourceType != SourceType.Library) - { - return; - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ItemAddedWithName"), Notifications.Notifications.GetItemName(e.Item)), - Type = "ItemAdded", - ItemId = e.Item.Id.ToString("N") - }); - } - - void _installationManager_PluginUpdated(object sender, GenericEventArgs> e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("PluginUpdatedWithName"), e.Argument.Item1.Name), - Type = "PluginUpdated", - ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.Item2.versionStr), - Overview = e.Argument.Item2.description - }); - } - - void _installationManager_PluginUninstalled(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("PluginUninstalledWithName"), e.Argument.Name), - Type = "PluginUninstalled" - }); - } - - void _installationManager_PluginInstalled(object sender, GenericEventArgs e) - { - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("PluginInstalledWithName"), e.Argument.name), - Type = "PluginInstalled", - ShortOverview = string.Format(_localization.GetLocalizedString("VersionNumber"), e.Argument.versionStr) - }); - } - - void _taskManager_TaskExecuting(object sender, GenericEventArgs e) - { - var task = e.Argument; - - var activityTask = task.ScheduledTask as IConfigurableScheduledTask; - if (activityTask != null && !activityTask.IsLogged) - { - return; - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ScheduledTaskStartedWithName"), task.Name), - Type = "ScheduledTaskStarted" - }); - } - - void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) - { - var result = e.Result; - var task = e.Task; - - var activityTask = task.ScheduledTask as IConfigurableScheduledTask; - if (activityTask != null && !activityTask.IsLogged) - { - return; - } - - var time = result.EndTimeUtc - result.StartTimeUtc; - var runningTime = string.Format(_localization.GetLocalizedString("LabelRunningTimeValue"), ToUserFriendlyString(time)); - - if (result.Status == TaskCompletionStatus.Failed) - { - var vals = new List(); - - if (!string.IsNullOrWhiteSpace(e.Result.ErrorMessage)) - { - vals.Add(e.Result.ErrorMessage); - } - if (!string.IsNullOrWhiteSpace(e.Result.LongErrorMessage)) - { - vals.Add(e.Result.LongErrorMessage); - } - - CreateLogEntry(new ActivityLogEntry - { - Name = string.Format(_localization.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name), - Type = "ScheduledTaskFailed", - Overview = string.Join(Environment.NewLine, vals.ToArray()), - ShortOverview = runningTime, - Severity = LogSeverity.Error - }); - } - } - - private async void CreateLogEntry(ActivityLogEntry entry) - { - try - { - await _activityManager.Create(entry).ConfigureAwait(false); - } - catch - { - // Logged at lower levels - } - } - - public void Dispose() - { - _taskManager.TaskExecuting -= _taskManager_TaskExecuting; - _taskManager.TaskCompleted -= _taskManager_TaskCompleted; - - _installationManager.PluginInstalled -= _installationManager_PluginInstalled; - _installationManager.PluginUninstalled -= _installationManager_PluginUninstalled; - _installationManager.PluginUpdated -= _installationManager_PluginUpdated; - - _libraryManager.ItemAdded -= _libraryManager_ItemAdded; - _libraryManager.ItemRemoved -= _libraryManager_ItemRemoved; - - _sessionManager.SessionStarted -= _sessionManager_SessionStarted; - _sessionManager.AuthenticationFailed -= _sessionManager_AuthenticationFailed; - _sessionManager.AuthenticationSucceeded -= _sessionManager_AuthenticationSucceeded; - _sessionManager.SessionEnded -= _sessionManager_SessionEnded; - - _sessionManager.PlaybackStart -= _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped -= _sessionManager_PlaybackStopped; - - _subManager.SubtitlesDownloaded -= _subManager_SubtitlesDownloaded; - _subManager.SubtitleDownloadFailure -= _subManager_SubtitleDownloadFailure; - - _userManager.UserCreated -= _userManager_UserCreated; - _userManager.UserPasswordChanged -= _userManager_UserPasswordChanged; - _userManager.UserDeleted -= _userManager_UserDeleted; - _userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated; - _userManager.UserLockedOut -= _userManager_UserLockedOut; - - _config.ConfigurationUpdated -= _config_ConfigurationUpdated; - _config.NamedConfigurationUpdated -= _config_NamedConfigurationUpdated; - - //_logManager.LoggerLoaded -= _logManager_LoggerLoaded; - - _appHost.ApplicationUpdated -= _appHost_ApplicationUpdated; - } - - /// - /// Constructs a user-friendly string for this TimeSpan instance. - /// - public static string ToUserFriendlyString(TimeSpan span) - { - const int DaysInYear = 365; - const int DaysInMonth = 30; - - // Get each non-zero value from TimeSpan component - List values = new List(); - - // Number of years - int days = span.Days; - if (days >= DaysInYear) - { - int years = days / DaysInYear; - values.Add(CreateValueString(years, "year")); - days = days % DaysInYear; - } - // Number of months - if (days >= DaysInMonth) - { - int months = days / DaysInMonth; - values.Add(CreateValueString(months, "month")); - days = days % DaysInMonth; - } - // Number of days - if (days >= 1) - values.Add(CreateValueString(days, "day")); - // Number of hours - if (span.Hours >= 1) - values.Add(CreateValueString(span.Hours, "hour")); - // Number of minutes - if (span.Minutes >= 1) - values.Add(CreateValueString(span.Minutes, "minute")); - // Number of seconds (include when 0 if no other components included) - if (span.Seconds >= 1 || values.Count == 0) - values.Add(CreateValueString(span.Seconds, "second")); - - // Combine values into string - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < values.Count; i++) - { - if (builder.Length > 0) - builder.Append(i == values.Count - 1 ? " and " : ", "); - builder.Append(values[i]); - } - // Return result - return builder.ToString(); - } - - /// - /// Constructs a string description of a time-span value. - /// - /// The value of this item - /// The name of this item (singular form) - private static string CreateValueString(int value, string description) - { - return String.Format("{0:#,##0} {1}", - value, value == 1 ? description : String.Format("{0}s", description)); - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs deleted file mode 100644 index f3d1dc8f9b..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifications.cs +++ /dev/null @@ -1,544 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Plugins; -using MediaBrowser.Common.Updates; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Devices; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Notifications; -using MediaBrowser.Model.Tasks; -using MediaBrowser.Model.Updates; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller.Entities.TV; - -namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications -{ - /// - /// Creates notifications for various system events - /// - public class Notifications : IServerEntryPoint - { - private readonly IInstallationManager _installationManager; - private readonly IUserManager _userManager; - private readonly ILogger _logger; - - private readonly ITaskManager _taskManager; - private readonly INotificationManager _notificationManager; - - private readonly ILibraryManager _libraryManager; - private readonly ISessionManager _sessionManager; - private readonly IServerApplicationHost _appHost; - - private Timer LibraryUpdateTimer { get; set; } - private readonly object _libraryChangedSyncLock = new object(); - - private readonly IConfigurationManager _config; - private readonly IDeviceManager _deviceManager; - - public Notifications(IInstallationManager installationManager, IUserManager userManager, ILogger logger, ITaskManager taskManager, INotificationManager notificationManager, ILibraryManager libraryManager, ISessionManager sessionManager, IServerApplicationHost appHost, IConfigurationManager config, IDeviceManager deviceManager) - { - _installationManager = installationManager; - _userManager = userManager; - _logger = logger; - _taskManager = taskManager; - _notificationManager = notificationManager; - _libraryManager = libraryManager; - _sessionManager = sessionManager; - _appHost = appHost; - _config = config; - _deviceManager = deviceManager; - } - - public void Run() - { - _installationManager.PluginInstalled += _installationManager_PluginInstalled; - _installationManager.PluginUpdated += _installationManager_PluginUpdated; - _installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed; - _installationManager.PluginUninstalled += _installationManager_PluginUninstalled; - - _taskManager.TaskCompleted += _taskManager_TaskCompleted; - - _userManager.UserCreated += _userManager_UserCreated; - _libraryManager.ItemAdded += _libraryManager_ItemAdded; - _sessionManager.PlaybackStart += _sessionManager_PlaybackStart; - _sessionManager.PlaybackStopped += _sessionManager_PlaybackStopped; - _appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged; - _appHost.HasUpdateAvailableChanged += _appHost_HasUpdateAvailableChanged; - _appHost.ApplicationUpdated += _appHost_ApplicationUpdated; - _deviceManager.CameraImageUploaded += _deviceManager_CameraImageUploaded; - - _userManager.UserLockedOut += _userManager_UserLockedOut; - } - - async void _userManager_UserLockedOut(object sender, GenericEventArgs e) - { - var type = NotificationType.UserLockedOut.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type - }; - - notification.Variables["UserName"] = e.Argument.Name; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _deviceManager_CameraImageUploaded(object sender, GenericEventArgs e) - { - var type = NotificationType.CameraImageUploaded.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type - }; - - notification.Variables["DeviceName"] = e.Argument.Device.Name; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _appHost_ApplicationUpdated(object sender, GenericEventArgs e) - { - var type = NotificationType.ApplicationUpdateInstalled.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type, - Url = e.Argument.infoUrl - }; - - notification.Variables["Version"] = e.Argument.versionStr; - notification.Variables["ReleaseNotes"] = e.Argument.description; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _installationManager_PluginUpdated(object sender, GenericEventArgs> e) - { - var type = NotificationType.PluginUpdateInstalled.ToString(); - - var installationInfo = e.Argument.Item1; - - var notification = new NotificationRequest - { - Description = e.Argument.Item2.description, - NotificationType = type - }; - - notification.Variables["Name"] = installationInfo.Name; - notification.Variables["Version"] = installationInfo.Version.ToString(); - notification.Variables["ReleaseNotes"] = e.Argument.Item2.description; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _installationManager_PluginInstalled(object sender, GenericEventArgs e) - { - var type = NotificationType.PluginInstalled.ToString(); - - var installationInfo = e.Argument; - - var notification = new NotificationRequest - { - Description = installationInfo.description, - NotificationType = type - }; - - notification.Variables["Name"] = installationInfo.name; - notification.Variables["Version"] = installationInfo.versionStr; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _appHost_HasUpdateAvailableChanged(object sender, EventArgs e) - { - // This notification is for users who can't auto-update (aka running as service) - if (!_appHost.HasUpdateAvailable || _appHost.CanSelfUpdate) - { - return; - } - - var type = NotificationType.ApplicationUpdateAvailable.ToString(); - - var notification = new NotificationRequest - { - Description = "Please see emby.media for details.", - NotificationType = type - }; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _appHost_HasPendingRestartChanged(object sender, EventArgs e) - { - if (!_appHost.HasPendingRestart) - { - return; - } - - var type = NotificationType.ServerRestartRequired.ToString(); - - var notification = new NotificationRequest - { - NotificationType = type - }; - - await SendNotification(notification).ConfigureAwait(false); - } - - private NotificationOptions GetOptions() - { - return _config.GetConfiguration("notifications"); - } - - void _sessionManager_PlaybackStart(object sender, PlaybackProgressEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - _logger.Warn("PlaybackStart reported with null media info."); - return; - } - - var video = e.Item as Video; - if (video != null && video.IsThemeMedia) - { - return; - } - - var type = GetPlaybackNotificationType(item.MediaType); - - SendPlaybackNotification(type, e); - } - - void _sessionManager_PlaybackStopped(object sender, PlaybackStopEventArgs e) - { - var item = e.MediaInfo; - - if (item == null) - { - _logger.Warn("PlaybackStopped reported with null media info."); - return; - } - - var video = e.Item as Video; - if (video != null && video.IsThemeMedia) - { - return; - } - - var type = GetPlaybackStoppedNotificationType(item.MediaType); - - SendPlaybackNotification(type, e); - } - - private async void SendPlaybackNotification(string type, PlaybackProgressEventArgs e) - { - var user = e.Users.FirstOrDefault(); - - if (user != null && !GetOptions().IsEnabledToMonitorUser(type, user.Id.ToString("N"))) - { - return; - } - - var item = e.MediaInfo; - - if ( item.IsThemeMedia) - { - // Don't report theme song or local trailer playback - return; - } - - var notification = new NotificationRequest - { - NotificationType = type - }; - - if (e.Item != null) - { - notification.Variables["ItemName"] = GetItemName(e.Item); - } - else - { - notification.Variables["ItemName"] = item.Name; - } - - notification.Variables["UserName"] = user == null ? "Unknown user" : user.Name; - notification.Variables["AppName"] = e.ClientName; - notification.Variables["DeviceName"] = e.DeviceName; - - await SendNotification(notification).ConfigureAwait(false); - } - - private string GetPlaybackNotificationType(string mediaType) - { - if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.AudioPlayback.ToString(); - } - if (string.Equals(mediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.GamePlayback.ToString(); - } - if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.VideoPlayback.ToString(); - } - - return null; - } - - private string GetPlaybackStoppedNotificationType(string mediaType) - { - if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.AudioPlaybackStopped.ToString(); - } - if (string.Equals(mediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.GamePlaybackStopped.ToString(); - } - if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) - { - return NotificationType.VideoPlaybackStopped.ToString(); - } - - return null; - } - - private readonly List _itemsAdded = new List(); - void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) - { - if (!FilterItem(e.Item)) - { - return; - } - - lock (_libraryChangedSyncLock) - { - if (LibraryUpdateTimer == null) - { - LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, 5000, - Timeout.Infinite); - } - else - { - LibraryUpdateTimer.Change(5000, Timeout.Infinite); - } - - _itemsAdded.Add(e.Item); - } - } - - private bool FilterItem(BaseItem item) - { - if (item.IsFolder) - { - return false; - } - - if (item.LocationType == LocationType.Virtual) - { - return false; - } - - if (item is IItemByName) - { - return false; - } - - return item.SourceType == SourceType.Library; - } - - private async void LibraryUpdateTimerCallback(object state) - { - List items; - - lock (_libraryChangedSyncLock) - { - items = _itemsAdded.ToList(); - _itemsAdded.Clear(); - DisposeLibraryUpdateTimer(); - } - - items = items.Take(10).ToList(); - - foreach (var item in items) - { - var notification = new NotificationRequest - { - NotificationType = NotificationType.NewLibraryContent.ToString() - }; - - notification.Variables["Name"] = GetItemName(item); - - await SendNotification(notification).ConfigureAwait(false); - } - } - - public static string GetItemName(BaseItem item) - { - var name = item.Name; - var episode = item as Episode; - if (episode != null) - { - if (episode.IndexNumber.HasValue) - { - name = string.Format("Ep{0} - {1}", episode.IndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); - } - if (episode.ParentIndexNumber.HasValue) - { - name = string.Format("S{0}, {1}", episode.ParentIndexNumber.Value.ToString(CultureInfo.InvariantCulture), name); - } - } - - var hasSeries = item as IHasSeries; - - if (hasSeries != null) - { - name = hasSeries.SeriesName + " - " + name; - } - - var hasArtist = item as IHasArtist; - if (hasArtist != null) - { - var artists = hasArtist.AllArtists; - - if (artists.Count > 0) - { - name = hasArtist.AllArtists[0] + " - " + name; - } - } - - return name; - } - - async void _userManager_UserCreated(object sender, GenericEventArgs e) - { - var notification = new NotificationRequest - { - UserIds = new List { e.Argument.Id.ToString("N") }, - Name = "Welcome to Emby!", - Description = "Check back here for more notifications." - }; - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) - { - var result = e.Result; - - if (result.Status == TaskCompletionStatus.Failed) - { - var type = NotificationType.TaskFailed.ToString(); - - var notification = new NotificationRequest - { - Description = result.ErrorMessage, - Level = NotificationLevel.Error, - NotificationType = type - }; - - notification.Variables["Name"] = result.Name; - notification.Variables["ErrorMessage"] = result.ErrorMessage; - - await SendNotification(notification).ConfigureAwait(false); - } - } - - async void _installationManager_PluginUninstalled(object sender, GenericEventArgs e) - { - var type = NotificationType.PluginUninstalled.ToString(); - - var plugin = e.Argument; - - var notification = new NotificationRequest - { - NotificationType = type - }; - - notification.Variables["Name"] = plugin.Name; - notification.Variables["Version"] = plugin.Version.ToString(); - - await SendNotification(notification).ConfigureAwait(false); - } - - async void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e) - { - var installationInfo = e.InstallationInfo; - - var type = NotificationType.InstallationFailed.ToString(); - - var notification = new NotificationRequest - { - Level = NotificationLevel.Error, - Description = e.Exception.Message, - NotificationType = type - }; - - notification.Variables["Name"] = installationInfo.Name; - notification.Variables["Version"] = installationInfo.Version; - - await SendNotification(notification).ConfigureAwait(false); - } - - private async Task SendNotification(NotificationRequest notification) - { - try - { - await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending notification", ex); - } - } - - public void Dispose() - { - DisposeLibraryUpdateTimer(); - - _installationManager.PluginInstalled -= _installationManager_PluginInstalled; - _installationManager.PluginUpdated -= _installationManager_PluginUpdated; - _installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed; - _installationManager.PluginUninstalled -= _installationManager_PluginUninstalled; - - _taskManager.TaskCompleted -= _taskManager_TaskCompleted; - - _userManager.UserCreated -= _userManager_UserCreated; - _libraryManager.ItemAdded -= _libraryManager_ItemAdded; - _sessionManager.PlaybackStart -= _sessionManager_PlaybackStart; - - _appHost.HasPendingRestartChanged -= _appHost_HasPendingRestartChanged; - _appHost.HasUpdateAvailableChanged -= _appHost_HasUpdateAvailableChanged; - _appHost.ApplicationUpdated -= _appHost_ApplicationUpdated; - - _deviceManager.CameraImageUploaded -= _deviceManager_CameraImageUploaded; - _userManager.UserLockedOut -= _userManager_UserLockedOut; - } - - private void DisposeLibraryUpdateTimer() - { - if (LibraryUpdateTimer != null) - { - LibraryUpdateTimer.Dispose(); - LibraryUpdateTimer = null; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs deleted file mode 100644 index 916b4a6224..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs +++ /dev/null @@ -1,54 +0,0 @@ -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Plugins; -using System.Linq; - -namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications -{ - /// - /// Notifies clients anytime a notification is added or udpated - /// - public class WebSocketNotifier : IServerEntryPoint - { - private readonly INotificationsRepository _notificationsRepo; - - private readonly IServerManager _serverManager; - - public WebSocketNotifier(INotificationsRepository notificationsRepo, IServerManager serverManager) - { - _notificationsRepo = notificationsRepo; - _serverManager = serverManager; - } - - public void Run() - { - _notificationsRepo.NotificationAdded += _notificationsRepo_NotificationAdded; - - _notificationsRepo.NotificationsMarkedRead += _notificationsRepo_NotificationsMarkedRead; - } - - void _notificationsRepo_NotificationsMarkedRead(object sender, NotificationReadEventArgs e) - { - var list = e.IdList.ToList(); - - list.Add(e.UserId); - list.Add(e.IsRead.ToString().ToLower()); - - var msg = string.Join("|", list.ToArray()); - - _serverManager.SendWebSocketMessage("NotificationsMarkedRead", msg); - } - - void _notificationsRepo_NotificationAdded(object sender, NotificationUpdateEventArgs e) - { - var msg = e.Notification.UserId + "|" + e.Notification.Id; - - _serverManager.SendWebSocketMessage("NotificationAdded", msg); - } - - public void Dispose() - { - _notificationsRepo.NotificationAdded -= _notificationsRepo_NotificationAdded; - } - } -} -- cgit v1.2.3 From 1d62a88fd8147e9c1bf01cac2852b929b1737c17 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Nov 2016 18:06:00 -0400 Subject: move classes to portable server project --- .../Emby.Server.Implementations.csproj | 11 + .../EntryPoints/AutomaticRestartEntryPoint.cs | 124 ++++++++ .../EntryPoints/LibraryChangedNotifier.cs | 343 +++++++++++++++++++++ .../EntryPoints/LoadRegistrations.cs | 73 +++++ .../EntryPoints/RecordingNotifier.cs | 77 +++++ .../EntryPoints/RefreshUsersMetadata.cs | 41 +++ .../EntryPoints/ServerEventNotifier.cs | 203 ++++++++++++ .../EntryPoints/UsageEntryPoint.cs | 133 ++++++++ .../EntryPoints/UsageReporter.cs | 138 +++++++++ .../EntryPoints/UserDataChangeNotifier.cs | 165 ++++++++++ .../MediaEncoder/EncodingManager.cs | 236 ++++++++++++++ Emby.Server.Implementations/News/NewsEntryPoint.cs | 260 ++++++++++++++++ Emby.Server.Implementations/project.json | 5 +- .../EntryPoints/AutomaticRestartEntryPoint.cs | 121 -------- .../EntryPoints/LibraryChangedNotifier.cs | 340 -------------------- .../EntryPoints/LoadRegistrations.cs | 71 ----- .../EntryPoints/RecordingNotifier.cs | 77 ----- .../EntryPoints/RefreshUsersMetadata.cs | 41 --- .../EntryPoints/ServerEventNotifier.cs | 203 ------------ .../EntryPoints/UsageEntryPoint.cs | 133 -------- .../EntryPoints/UsageReporter.cs | 138 --------- .../EntryPoints/UserDataChangeNotifier.cs | 162 ---------- .../MediaBrowser.Server.Implementations.csproj | 137 ++++---- .../MediaEncoder/EncodingManager.cs | 236 -------------- .../News/NewsEntryPoint.cs | 170 ---------- .../packages.config | 3 +- .../ApplicationHost.cs | 2 +- .../MediaBrowser.Server.Startup.Common.csproj | 4 + MediaBrowser.Server.Startup.Common/packages.config | 1 + .../MediaBrowser.XbmcMetadata.csproj | 5 - MediaBrowser.XbmcMetadata/packages.config | 1 - 31 files changed, 1872 insertions(+), 1782 deletions(-) create mode 100644 Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs create mode 100644 Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs create mode 100644 Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs create mode 100644 Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs create mode 100644 Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs create mode 100644 Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs create mode 100644 Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs create mode 100644 Emby.Server.Implementations/EntryPoints/UsageReporter.cs create mode 100644 Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs create mode 100644 Emby.Server.Implementations/MediaEncoder/EncodingManager.cs create mode 100644 Emby.Server.Implementations/News/NewsEntryPoint.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs delete mode 100644 MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs delete mode 100644 MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs delete mode 100644 MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 4a32d00a2d..e3d4046442 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -51,6 +51,15 @@ + + + + + + + + + @@ -100,6 +109,8 @@ + + diff --git a/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs new file mode 100644 index 0000000000..38708648fe --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs @@ -0,0 +1,124 @@ +using MediaBrowser.Controller; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Tasks; +using System; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.EntryPoints +{ + public class AutomaticRestartEntryPoint : IServerEntryPoint + { + private readonly IServerApplicationHost _appHost; + private readonly ILogger _logger; + private readonly ITaskManager _iTaskManager; + private readonly ISessionManager _sessionManager; + private readonly IServerConfigurationManager _config; + private readonly ILiveTvManager _liveTvManager; + private readonly ITimerFactory _timerFactory; + + private ITimer _timer; + + public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager, ITimerFactory timerFactory) + { + _appHost = appHost; + _logger = logger; + _iTaskManager = iTaskManager; + _sessionManager = sessionManager; + _config = config; + _liveTvManager = liveTvManager; + _timerFactory = timerFactory; + } + + public void Run() + { + if (_appHost.CanSelfRestart) + { + _appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged; + } + } + + void _appHost_HasPendingRestartChanged(object sender, EventArgs e) + { + DisposeTimer(); + + if (_appHost.HasPendingRestart) + { + _timer = _timerFactory.Create(TimerCallback, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); + } + } + + private async void TimerCallback(object state) + { + if (_config.Configuration.EnableAutomaticRestart) + { + var isIdle = await IsIdle().ConfigureAwait(false); + + if (isIdle) + { + DisposeTimer(); + + try + { + _appHost.Restart(); + } + catch (Exception ex) + { + _logger.ErrorException("Error restarting server", ex); + } + } + } + } + + private async Task IsIdle() + { + if (_iTaskManager.ScheduledTasks.Any(i => i.State != TaskState.Idle)) + { + return false; + } + + if (_liveTvManager.Services.Count == 1) + { + try + { + var timers = await _liveTvManager.GetTimers(new TimerQuery(), CancellationToken.None).ConfigureAwait(false); + if (timers.Items.Any(i => i.Status == RecordingStatus.InProgress)) + { + return false; + } + } + catch (Exception ex) + { + _logger.ErrorException("Error getting timers", ex); + } + } + + var now = DateTime.UtcNow; + + return !_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 30); + } + + public void Dispose() + { + _appHost.HasPendingRestartChanged -= _appHost_HasPendingRestartChanged; + + DisposeTimer(); + } + + private void DisposeTimer() + { + if (_timer != null) + { + _timer.Dispose(); + _timer = null; + } + } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs new file mode 100644 index 0000000000..91142f9284 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs @@ -0,0 +1,343 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.EntryPoints +{ + public class LibraryChangedNotifier : IServerEntryPoint + { + /// + /// The _library manager + /// + private readonly ILibraryManager _libraryManager; + + private readonly ISessionManager _sessionManager; + private readonly IUserManager _userManager; + private readonly ILogger _logger; + private readonly ITimerFactory _timerFactory; + + /// + /// The _library changed sync lock + /// + private readonly object _libraryChangedSyncLock = new object(); + + private readonly List _foldersAddedTo = new List(); + private readonly List _foldersRemovedFrom = new List(); + + private readonly List _itemsAdded = new List(); + private readonly List _itemsRemoved = new List(); + private readonly List _itemsUpdated = new List(); + + /// + /// Gets or sets the library update timer. + /// + /// The library update timer. + private ITimer LibraryUpdateTimer { get; set; } + + /// + /// The library update duration + /// + private const int LibraryUpdateDuration = 5000; + + public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IUserManager userManager, ILogger logger, ITimerFactory timerFactory) + { + _libraryManager = libraryManager; + _sessionManager = sessionManager; + _userManager = userManager; + _logger = logger; + _timerFactory = timerFactory; + } + + public void Run() + { + _libraryManager.ItemAdded += libraryManager_ItemAdded; + _libraryManager.ItemUpdated += libraryManager_ItemUpdated; + _libraryManager.ItemRemoved += libraryManager_ItemRemoved; + + } + + /// + /// Handles the ItemAdded event of the libraryManager control. + /// + /// The source of the event. + /// The instance containing the event data. + void libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) + { + if (!FilterItem(e.Item)) + { + return; + } + + lock (_libraryChangedSyncLock) + { + if (LibraryUpdateTimer == null) + { + LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, + Timeout.Infinite); + } + else + { + LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); + } + + if (e.Item.Parent != null) + { + _foldersAddedTo.Add(e.Item.Parent); + } + + _itemsAdded.Add(e.Item); + } + } + + /// + /// Handles the ItemUpdated event of the libraryManager control. + /// + /// The source of the event. + /// The instance containing the event data. + void libraryManager_ItemUpdated(object sender, ItemChangeEventArgs e) + { + if (!FilterItem(e.Item)) + { + return; + } + + lock (_libraryChangedSyncLock) + { + if (LibraryUpdateTimer == null) + { + LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, + Timeout.Infinite); + } + else + { + LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); + } + + _itemsUpdated.Add(e.Item); + } + } + + /// + /// Handles the ItemRemoved event of the libraryManager control. + /// + /// The source of the event. + /// The instance containing the event data. + void libraryManager_ItemRemoved(object sender, ItemChangeEventArgs e) + { + if (!FilterItem(e.Item)) + { + return; + } + + lock (_libraryChangedSyncLock) + { + if (LibraryUpdateTimer == null) + { + LibraryUpdateTimer = _timerFactory.Create(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, + Timeout.Infinite); + } + else + { + LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); + } + + if (e.Item.Parent != null) + { + _foldersRemovedFrom.Add(e.Item.Parent); + } + + _itemsRemoved.Add(e.Item); + } + } + + /// + /// Libraries the update timer callback. + /// + /// The state. + private void LibraryUpdateTimerCallback(object state) + { + lock (_libraryChangedSyncLock) + { + // Remove dupes in case some were saved multiple times + var foldersAddedTo = _foldersAddedTo.DistinctBy(i => i.Id).ToList(); + + var foldersRemovedFrom = _foldersRemovedFrom.DistinctBy(i => i.Id).ToList(); + + var itemsUpdated = _itemsUpdated + .Where(i => !_itemsAdded.Contains(i)) + .DistinctBy(i => i.Id) + .ToList(); + + SendChangeNotifications(_itemsAdded.ToList(), itemsUpdated, _itemsRemoved.ToList(), foldersAddedTo, foldersRemovedFrom, CancellationToken.None); + + if (LibraryUpdateTimer != null) + { + LibraryUpdateTimer.Dispose(); + LibraryUpdateTimer = null; + } + + _itemsAdded.Clear(); + _itemsRemoved.Clear(); + _itemsUpdated.Clear(); + _foldersAddedTo.Clear(); + _foldersRemovedFrom.Clear(); + } + } + + /// + /// Sends the change notifications. + /// + /// The items added. + /// The items updated. + /// The items removed. + /// The folders added to. + /// The folders removed from. + /// The cancellation token. + private async void SendChangeNotifications(List itemsAdded, List itemsUpdated, List itemsRemoved, List foldersAddedTo, List foldersRemovedFrom, CancellationToken cancellationToken) + { + foreach (var user in _userManager.Users.ToList()) + { + var id = user.Id; + var userSessions = _sessionManager.Sessions + .Where(u => u.UserId.HasValue && u.UserId.Value == id && u.SessionController != null && u.IsActive) + .ToList(); + + if (userSessions.Count > 0) + { + 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); + } + } + } + + } + } + + /// + /// Gets the library update info. + /// + /// The items added. + /// The items updated. + /// The items removed. + /// The folders added to. + /// The folders removed from. + /// The user id. + /// LibraryUpdateInfo. + private LibraryUpdateInfo GetLibraryUpdateInfo(IEnumerable itemsAdded, IEnumerable itemsUpdated, IEnumerable itemsRemoved, IEnumerable foldersAddedTo, IEnumerable foldersRemovedFrom, Guid userId) + { + var user = _userManager.GetUserById(userId); + + return new LibraryUpdateInfo + { + ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + + ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + + ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + + FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), + + FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList() + }; + } + + private bool FilterItem(BaseItem item) + { + if (!item.IsFolder && item.LocationType == LocationType.Virtual) + { + return false; + } + + if (item is IItemByName && !(item is MusicArtist)) + { + return false; + } + + return item.SourceType == SourceType.Library; + } + + /// + /// Translates the physical item to user library. + /// + /// + /// The item. + /// The user. + /// if set to true [include if not found]. + /// IEnumerable{``0}. + private IEnumerable TranslatePhysicalItemToUserLibrary(T item, User user, bool includeIfNotFound = false) + where T : BaseItem + { + // If the physical root changed, return the user root + if (item is AggregateFolder) + { + return new[] { user.RootFolder as T }; + } + + // Return it only if it's in the user's library + if (includeIfNotFound || item.IsVisibleStandalone(user)) + { + return new[] { item }; + } + + return new T[] { }; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + if (LibraryUpdateTimer != null) + { + LibraryUpdateTimer.Dispose(); + LibraryUpdateTimer = null; + } + + _libraryManager.ItemAdded -= libraryManager_ItemAdded; + _libraryManager.ItemUpdated -= libraryManager_ItemUpdated; + _libraryManager.ItemRemoved -= libraryManager_ItemRemoved; + } + } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs b/Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs new file mode 100644 index 0000000000..0203b51928 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/LoadRegistrations.cs @@ -0,0 +1,73 @@ +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 +{ + /// + /// Class LoadRegistrations + /// + public class LoadRegistrations : IServerEntryPoint + { + /// + /// The _security manager + /// + private readonly ISecurityManager _securityManager; + + /// + /// The _logger + /// + private readonly ILogger _logger; + + private ITimer _timer; + private readonly ITimerFactory _timerFactory; + + /// + /// Initializes a new instance of the class. + /// + /// The security manager. + /// The log manager. + public LoadRegistrations(ISecurityManager securityManager, ILogManager logManager, ITimerFactory timerFactory) + { + _securityManager = securityManager; + _timerFactory = timerFactory; + + _logger = logManager.GetLogger("Registration Loader"); + } + + /// + /// Runs this instance. + /// + 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); + } + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + if (_timer != null) + { + _timer.Dispose(); + _timer = null; + } + } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs new file mode 100644 index 0000000000..b674fc39bb --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/RecordingNotifier.cs @@ -0,0 +1,77 @@ +using System; +using System.Linq; +using System.Threading; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Logging; + +namespace Emby.Server.Implementations.EntryPoints +{ + public class RecordingNotifier : IServerEntryPoint + { + private readonly ILiveTvManager _liveTvManager; + private readonly ISessionManager _sessionManager; + private readonly IUserManager _userManager; + private readonly ILogger _logger; + + public RecordingNotifier(ISessionManager sessionManager, IUserManager userManager, ILogger logger, ILiveTvManager liveTvManager) + { + _sessionManager = sessionManager; + _userManager = userManager; + _logger = logger; + _liveTvManager = liveTvManager; + } + + public void Run() + { + _liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled; + _liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled; + _liveTvManager.TimerCreated += _liveTvManager_TimerCreated; + _liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated; + } + + private void _liveTvManager_SeriesTimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs e) + { + SendMessage("SeriesTimerCreated", e.Argument); + } + + private void _liveTvManager_TimerCreated(object sender, MediaBrowser.Model.Events.GenericEventArgs e) + { + SendMessage("TimerCreated", e.Argument); + } + + private void _liveTvManager_SeriesTimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs e) + { + SendMessage("SeriesTimerCancelled", e.Argument); + } + + private void _liveTvManager_TimerCancelled(object sender, MediaBrowser.Model.Events.GenericEventArgs e) + { + SendMessage("TimerCancelled", e.Argument); + } + + private async void SendMessage(string name, TimerEventInfo info) + { + var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id.ToString("N")).ToList(); + + try + { + await _sessionManager.SendMessageToUserSessions(users, name, info, CancellationToken.None); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending message", ex); + } + } + + public void Dispose() + { + _liveTvManager.TimerCancelled -= _liveTvManager_TimerCancelled; + _liveTvManager.SeriesTimerCancelled -= _liveTvManager_SeriesTimerCancelled; + _liveTvManager.TimerCreated -= _liveTvManager_TimerCreated; + _liveTvManager.SeriesTimerCreated -= _liveTvManager_SeriesTimerCreated; + } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs new file mode 100644 index 0000000000..77de849a17 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs @@ -0,0 +1,41 @@ +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; +using System.Threading; + +namespace Emby.Server.Implementations.EntryPoints +{ + /// + /// Class RefreshUsersMetadata + /// + public class RefreshUsersMetadata : IServerEntryPoint + { + /// + /// The _user manager + /// + private readonly IUserManager _userManager; + + /// + /// Initializes a new instance of the class. + /// + /// The user manager. + public RefreshUsersMetadata(IUserManager userManager) + { + _userManager = userManager; + } + + /// + /// Runs this instance. + /// + public async void Run() + { + await _userManager.RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs new file mode 100644 index 0000000000..4d640bc95d --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/ServerEventNotifier.cs @@ -0,0 +1,203 @@ +using MediaBrowser.Common.Plugins; +using MediaBrowser.Common.Updates; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Net; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Sync; +using System; +using System.Collections.Generic; +using System.Threading; +using MediaBrowser.Model.Tasks; + +namespace Emby.Server.Implementations.EntryPoints +{ + /// + /// Class WebSocketEvents + /// + public class ServerEventNotifier : IServerEntryPoint + { + /// + /// The _server manager + /// + private readonly IServerManager _serverManager; + + /// + /// The _user manager + /// + private readonly IUserManager _userManager; + + /// + /// The _installation manager + /// + private readonly IInstallationManager _installationManager; + + /// + /// The _kernel + /// + private readonly IServerApplicationHost _appHost; + + /// + /// The _task manager + /// + 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) + { + _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.UserConfigurationUpdated += _userManager_UserConfigurationUpdated; + + _appHost.HasPendingRestartChanged += kernel_HasPendingRestartChanged; + + _installationManager.PluginUninstalled += InstallationManager_PluginUninstalled; + _installationManager.PackageInstalling += _installationManager_PackageInstalling; + _installationManager.PackageInstallationCancelled += _installationManager_PackageInstallationCancelled; + _installationManager.PackageInstallationCompleted += _installationManager_PackageInstallationCompleted; + _installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed; + + _taskManager.TaskCompleted += _taskManager_TaskCompleted; + _syncManager.SyncJobCreated += _syncManager_SyncJobCreated; + _syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled; + } + + void _syncManager_SyncJobCancelled(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToUserDeviceSessions(e.Argument.TargetId, "SyncJobCancelled", e.Argument, CancellationToken.None); + } + + void _syncManager_SyncJobCreated(object sender, GenericEventArgs e) + { + _sessionManager.SendMessageToUserDeviceSessions(e.Argument.Job.TargetId, "SyncJobCreated", e.Argument, CancellationToken.None); + } + + void _installationManager_PackageInstalling(object sender, InstallationEventArgs e) + { + _serverManager.SendWebSocketMessage("PackageInstalling", e.InstallationInfo); + } + + void _installationManager_PackageInstallationCancelled(object sender, InstallationEventArgs e) + { + _serverManager.SendWebSocketMessage("PackageInstallationCancelled", e.InstallationInfo); + } + + void _installationManager_PackageInstallationCompleted(object sender, InstallationEventArgs e) + { + _serverManager.SendWebSocketMessage("PackageInstallationCompleted", e.InstallationInfo); + } + + void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e) + { + _serverManager.SendWebSocketMessage("PackageInstallationFailed", e.InstallationInfo); + } + + void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) + { + _serverManager.SendWebSocketMessage("ScheduledTaskEnded", e.Result); + } + + /// + /// Installations the manager_ plugin uninstalled. + /// + /// The sender. + /// The e. + void InstallationManager_PluginUninstalled(object sender, GenericEventArgs e) + { + _serverManager.SendWebSocketMessage("PluginUninstalled", e.Argument.GetPluginInfo()); + } + + /// + /// Handles the HasPendingRestartChanged event of the kernel control. + /// + /// The source of the event. + /// The instance containing the event data. + void kernel_HasPendingRestartChanged(object sender, EventArgs e) + { + _sessionManager.SendRestartRequiredNotification(CancellationToken.None); + } + + /// + /// Users the manager_ user updated. + /// + /// The sender. + /// The e. + void userManager_UserUpdated(object sender, GenericEventArgs e) + { + var dto = _userManager.GetUserDto(e.Argument); + + SendMessageToUserSession(e.Argument, "UserUpdated", dto); + } + + /// + /// Users the manager_ user deleted. + /// + /// The sender. + /// The e. + void userManager_UserDeleted(object sender, GenericEventArgs e) + { + SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N")); + } + + void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs e) + { + var dto = _userManager.GetUserDto(e.Argument); + + SendMessageToUserSession(e.Argument, "UserConfigurationUpdated", dto); + } + + private async void SendMessageToUserSession(User user, string name, T data) + { + await _sessionManager.SendMessageToUserSessions(new List { user.Id.ToString("N") }, name, data, CancellationToken.None); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + Dispose(true); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool dispose) + { + if (dispose) + { + _userManager.UserDeleted -= userManager_UserDeleted; + _userManager.UserUpdated -= userManager_UserUpdated; + _userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated; + + _installationManager.PluginUninstalled -= InstallationManager_PluginUninstalled; + _installationManager.PackageInstalling -= _installationManager_PackageInstalling; + _installationManager.PackageInstallationCancelled -= _installationManager_PackageInstallationCancelled; + _installationManager.PackageInstallationCompleted -= _installationManager_PackageInstallationCompleted; + _installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed; + + _appHost.HasPendingRestartChanged -= kernel_HasPendingRestartChanged; + _syncManager.SyncJobCreated -= _syncManager_SyncJobCreated; + _syncManager.SyncJobCancelled -= _syncManager_SyncJobCancelled; + } + } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs new file mode 100644 index 0000000000..1b897ca299 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs @@ -0,0 +1,133 @@ +using MediaBrowser.Common; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Library; +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; +using System.Threading.Tasks; +using MediaBrowser.Controller.Configuration; + +namespace Emby.Server.Implementations.EntryPoints +{ + /// + /// Class UsageEntryPoint + /// + public class UsageEntryPoint : IServerEntryPoint + { + private readonly IApplicationHost _applicationHost; + private readonly IHttpClient _httpClient; + private readonly ILogger _logger; + private readonly ISessionManager _sessionManager; + private readonly IUserManager _userManager; + private readonly IServerConfigurationManager _config; + + private readonly ConcurrentDictionary _apps = new ConcurrentDictionary(); + + public UsageEntryPoint(ILogger logger, IApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config) + { + _logger = logger; + _applicationHost = applicationHost; + _httpClient = httpClient; + _sessionManager = sessionManager; + _userManager = userManager; + _config = config; + + _sessionManager.SessionStarted += _sessionManager_SessionStarted; + } + + void _sessionManager_SessionStarted(object sender, SessionEventArgs e) + { + var session = e.SessionInfo; + + if (!string.IsNullOrEmpty(session.Client) && + !string.IsNullOrEmpty(session.DeviceName) && + !string.IsNullOrEmpty(session.DeviceId) && + !string.IsNullOrEmpty(session.ApplicationVersion)) + { + var keys = new List + { + session.Client, + session.DeviceName, + session.DeviceId, + session.ApplicationVersion + }; + + var key = string.Join("_", keys.ToArray()).GetMD5(); + + _apps.GetOrAdd(key, guid => GetNewClientInfo(session)); + } + } + + private async void ReportNewSession(ClientInfo client) + { + if (!_config.Configuration.EnableAnonymousUsageReporting) + { + return; + } + + try + { + await new UsageReporter(_applicationHost, _httpClient, _userManager, _logger) + .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, + DeviceName = session.DeviceName, + DeviceId = session.DeviceId + }; + + ReportNewSession(info); + + return info; + } + + public async void Run() + { + await Task.Delay(5000).ConfigureAwait(false); + OnTimerFired(); + } + + /// + /// Called when [timer fired]. + /// + private async void OnTimerFired() + { + if (!_config.Configuration.EnableAnonymousUsageReporting) + { + return; + } + + try + { + await new UsageReporter(_applicationHost, _httpClient, _userManager, _logger) + .ReportServerUsage(CancellationToken.None) + .ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending anonymous usage statistics.", ex); + } + } + + public void Dispose() + { + _sessionManager.SessionStarted -= _sessionManager_SessionStarted; + } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs new file mode 100644 index 0000000000..be848acb77 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs @@ -0,0 +1,138 @@ +using MediaBrowser.Common; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Connect; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Logging; + +namespace Emby.Server.Implementations.EntryPoints +{ + public class UsageReporter + { + private readonly IApplicationHost _applicationHost; + private readonly IHttpClient _httpClient; + private readonly IUserManager _userManager; + private readonly ILogger _logger; + private const string MbAdminUrl = "https://www.mb3admin.com/admin/"; + + public UsageReporter(IApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger) + { + _applicationHost = applicationHost; + _httpClient = httpClient; + _userManager = userManager; + _logger = logger; + } + + public async Task ReportServerUsage(CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + var data = new Dictionary + { + { "feature", _applicationHost.Name }, + { "mac", _applicationHost.SystemId }, + { "serverid", _applicationHost.SystemId }, + { "deviceid", _applicationHost.SystemId }, + { "ver", _applicationHost.ApplicationVersion.ToString() }, + { "platform", _applicationHost.OperatingSystemDisplayName }, + { "isservice", _applicationHost.IsRunningAsService.ToString().ToLower()} + }; + + var users = _userManager.Users.ToList(); + + data["localusers"] = users.Count(i => !i.ConnectLinkType.HasValue).ToString(CultureInfo.InvariantCulture); + data["guests"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest).ToString(CultureInfo.InvariantCulture); + data["linkedusers"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.LinkedUser).ToString(CultureInfo.InvariantCulture); + + data["plugins"] = string.Join(",", _applicationHost.Plugins.Select(i => i.Id).ToArray()); + + var logErrors = false; +#if DEBUG + logErrors = true; +#endif + var options = new HttpRequestOptions + { + Url = MbAdminUrl + "service/registration/ping", + CancellationToken = cancellationToken, + + // Seeing block length errors + EnableHttpCompression = false, + + LogRequest = false, + LogErrors = logErrors, + BufferContent = false + }; + + options.SetPostData(data); + + using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) + { + + } + } + + public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) + { + if (string.IsNullOrWhiteSpace(app.DeviceId)) + { + throw new ArgumentException("Client info must have a device Id"); + } + + _logger.Info("App Activity: app: {0}, version: {1}, deviceId: {2}, deviceName: {3}", + app.AppName ?? "Unknown App", + app.AppVersion ?? "Unknown", + app.DeviceId, + app.DeviceName ?? "Unknown"); + + cancellationToken.ThrowIfCancellationRequested(); + + var data = new Dictionary + { + { "feature", app.AppName ?? "Unknown App" }, + { "serverid", _applicationHost.SystemId }, + { "deviceid", app.DeviceId }, + { "mac", app.DeviceId }, + { "ver", app.AppVersion ?? "Unknown" }, + { "platform", app.DeviceName }, + }; + + var logErrors = false; + +#if DEBUG + logErrors = true; +#endif + var options = new HttpRequestOptions + { + Url = MbAdminUrl + "service/registration/ping", + CancellationToken = cancellationToken, + + // Seeing block length errors + EnableHttpCompression = false, + + LogRequest = false, + LogErrors = logErrors, + BufferContent = false + }; + + options.SetPostData(data); + + using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) + { + + } + } + } + + public class ClientInfo + { + public string AppName { get; set; } + public string AppVersion { get; set; } + public string DeviceName { get; set; } + public string DeviceId { get; set; } + } +} diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs new file mode 100644 index 0000000000..b934101809 --- /dev/null +++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs @@ -0,0 +1,165 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Controller.Session; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Session; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Model.Extensions; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.EntryPoints +{ + class UserDataChangeNotifier : IServerEntryPoint + { + private readonly ISessionManager _sessionManager; + private readonly ILogger _logger; + private readonly IUserDataManager _userDataManager; + private readonly IUserManager _userManager; + + private readonly object _syncLock = new object(); + private ITimer UpdateTimer { get; set; } + private readonly ITimerFactory _timerFactory; + private const int UpdateDuration = 500; + + private readonly Dictionary> _changedItems = new Dictionary>(); + + public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, ILogger logger, IUserManager userManager, ITimerFactory timerFactory) + { + _userDataManager = userDataManager; + _sessionManager = sessionManager; + _logger = logger; + _userManager = userManager; + _timerFactory = timerFactory; + } + + public void Run() + { + _userDataManager.UserDataSaved += _userDataManager_UserDataSaved; + } + + void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e) + { + if (e.SaveReason == UserDataSaveReason.PlaybackProgress) + { + return; + } + + lock (_syncLock) + { + if (UpdateTimer == null) + { + UpdateTimer = _timerFactory.Create(UpdateTimerCallback, null, UpdateDuration, + Timeout.Infinite); + } + else + { + UpdateTimer.Change(UpdateDuration, Timeout.Infinite); + } + + List keys; + + if (!_changedItems.TryGetValue(e.UserId, out keys)) + { + keys = new List(); + _changedItems[e.UserId] = keys; + } + + keys.Add(e.Item); + + var baseItem = e.Item as BaseItem; + + // Go up one level for indicators + if (baseItem != null) + { + var parent = baseItem.GetParent(); + + if (parent != null) + { + keys.Add(parent); + } + } + } + } + + private void UpdateTimerCallback(object state) + { + lock (_syncLock) + { + // Remove dupes in case some were saved multiple times + var changes = _changedItems.ToList(); + _changedItems.Clear(); + + var task = SendNotifications(changes, CancellationToken.None); + + if (UpdateTimer != null) + { + UpdateTimer.Dispose(); + UpdateTimer = null; + } + } + } + + private async Task SendNotifications(IEnumerable>> 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).Result; + dto.ItemId = i.Id.ToString("N"); + return dto; + }) + .ToList(); + + 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); + } + } + } + + } + } + + public void Dispose() + { + if (UpdateTimer != null) + { + UpdateTimer.Dispose(); + UpdateTimer = null; + } + + _userDataManager.UserDataSaved -= _userDataManager_UserDataSaved; + } + } +} diff --git a/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs new file mode 100644 index 0000000000..204e04061d --- /dev/null +++ b/Emby.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -0,0 +1,236 @@ +using MediaBrowser.Controller.Chapters; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.MediaEncoding; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Controller.Library; + +namespace Emby.Server.Implementations.MediaEncoder +{ + public class EncodingManager : IEncodingManager + { + private readonly CultureInfo _usCulture = new CultureInfo("en-US"); + private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; + private readonly IMediaEncoder _encoder; + private readonly IChapterManager _chapterManager; + private readonly ILibraryManager _libraryManager; + + public EncodingManager(IFileSystem fileSystem, + ILogger logger, + IMediaEncoder encoder, + IChapterManager chapterManager, ILibraryManager libraryManager) + { + _fileSystem = fileSystem; + _logger = logger; + _encoder = encoder; + _chapterManager = chapterManager; + _libraryManager = libraryManager; + } + + /// + /// Gets the chapter images data path. + /// + /// The chapter images data path. + private string GetChapterImagesPath(IHasImages item) + { + return Path.Combine(item.GetInternalMetadataPath(), "chapters"); + } + + /// + /// Determines whether [is eligible for chapter image extraction] [the specified video]. + /// + /// The video. + /// true if [is eligible for chapter image extraction] [the specified video]; otherwise, false. + private bool IsEligibleForChapterImageExtraction(Video video) + { + if (video.IsPlaceHolder) + { + return false; + } + + var libraryOptions = _libraryManager.GetLibraryOptions(video); + if (libraryOptions != null) + { + if (!libraryOptions.EnableChapterImageExtraction) + { + return false; + } + } + else + { + return false; + } + + // Can't extract images if there are no video streams + return video.DefaultVideoStreamIndex.HasValue; + } + + /// + /// The first chapter ticks + /// + private static readonly long FirstChapterTicks = TimeSpan.FromSeconds(15).Ticks; + + public async Task RefreshChapterImages(ChapterImageRefreshOptions options, CancellationToken cancellationToken) + { + var extractImages = options.ExtractImages; + var video = options.Video; + var chapters = options.Chapters; + var saveChapters = options.SaveChapters; + + if (!IsEligibleForChapterImageExtraction(video)) + { + extractImages = false; + } + + var success = true; + var changesMade = false; + + var runtimeTicks = video.RunTimeTicks ?? 0; + + var currentImages = GetSavedChapterImages(video); + + foreach (var chapter in chapters) + { + if (chapter.StartPositionTicks >= runtimeTicks) + { + _logger.Info("Stopping chapter extraction for {0} because a chapter was found with a position greater than the runtime.", video.Name); + break; + } + + var path = GetChapterImagePath(video, chapter.StartPositionTicks); + + if (!currentImages.Contains(path, StringComparer.OrdinalIgnoreCase)) + { + if (extractImages) + { + if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso) + { + continue; + } + if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd) + { + if (video.PlayableStreamFileNames.Count != 1) + { + continue; + } + } + + try + { + // Add some time for the first chapter to make sure we don't end up with a black image + var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks); + + var protocol = MediaProtocol.File; + + var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames); + + _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); + + var container = video.Container; + + var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false); + _fileSystem.CopyFile(tempFile, path, true); + + try + { + _fileSystem.DeleteFile(tempFile); + } + catch + { + + } + + chapter.ImagePath = path; + chapter.ImageDateModified = _fileSystem.GetLastWriteTimeUtc(path); + changesMade = true; + } + catch (Exception ex) + { + _logger.ErrorException("Error extracting chapter images for {0}", ex, string.Join(",", video.Path)); + success = false; + break; + } + } + else if (!string.IsNullOrEmpty(chapter.ImagePath)) + { + chapter.ImagePath = null; + changesMade = true; + } + } + else if (!string.Equals(path, chapter.ImagePath, StringComparison.OrdinalIgnoreCase)) + { + chapter.ImagePath = path; + chapter.ImageDateModified = _fileSystem.GetLastWriteTimeUtc(path); + changesMade = true; + } + } + + if (saveChapters && changesMade) + { + await _chapterManager.SaveChapters(video.Id.ToString(), chapters, cancellationToken).ConfigureAwait(false); + } + + DeleteDeadImages(currentImages, chapters); + + return success; + } + + private string GetChapterImagePath(Video video, long chapterPositionTicks) + { + var filename = video.DateModified.Ticks.ToString(_usCulture) + "_" + chapterPositionTicks.ToString(_usCulture) + ".jpg"; + + return Path.Combine(GetChapterImagesPath(video), filename); + } + + private List GetSavedChapterImages(Video video) + { + var path = GetChapterImagesPath(video); + + try + { + return _fileSystem.GetFilePaths(path) + .ToList(); + } + catch (IOException) + { + return new List(); + } + } + + private void DeleteDeadImages(IEnumerable images, IEnumerable chapters) + { + var deadImages = images + .Except(chapters.Select(i => i.ImagePath).Where(i => !string.IsNullOrEmpty(i)), StringComparer.OrdinalIgnoreCase) + .Where(i => BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i), StringComparer.OrdinalIgnoreCase)) + .ToList(); + + foreach (var image in deadImages) + { + _logger.Debug("Deleting dead chapter image {0}", image); + + try + { + _fileSystem.DeleteFile(image); + } + catch (IOException ex) + { + _logger.ErrorException("Error deleting {0}.", ex, image); + } + } + } + } +} diff --git a/Emby.Server.Implementations/News/NewsEntryPoint.cs b/Emby.Server.Implementations/News/NewsEntryPoint.cs new file mode 100644 index 0000000000..1497d066fe --- /dev/null +++ b/Emby.Server.Implementations/News/NewsEntryPoint.cs @@ -0,0 +1,260 @@ +using MediaBrowser.Common.Configuration; +using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Net; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Notifications; +using MediaBrowser.Controller.Plugins; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.News; +using MediaBrowser.Model.Notifications; +using MediaBrowser.Model.Serialization; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Xml; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Threading; + +namespace Emby.Server.Implementations.News +{ + public class NewsEntryPoint : IServerEntryPoint + { + private ITimer _timer; + private readonly IHttpClient _httpClient; + private readonly IApplicationPaths _appPaths; + private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; + private readonly IJsonSerializer _json; + + private readonly INotificationManager _notifications; + private readonly IUserManager _userManager; + + private readonly TimeSpan _frequency = TimeSpan.FromHours(24); + private readonly ITimerFactory _timerFactory; + + public NewsEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IJsonSerializer json, INotificationManager notifications, IUserManager userManager, ITimerFactory timerFactory) + { + _httpClient = httpClient; + _appPaths = appPaths; + _fileSystem = fileSystem; + _logger = logger; + _json = json; + _notifications = notifications; + _userManager = userManager; + _timerFactory = timerFactory; + } + + public void Run() + { + _timer = _timerFactory.Create(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency); + } + + /// + /// Called when [timer fired]. + /// + /// The state. + private async void OnTimerFired(object state) + { + var path = Path.Combine(_appPaths.CachePath, "news.json"); + + try + { + await DownloadNews(path).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error downloading news", ex); + } + } + + private async Task DownloadNews(string path) + { + DateTime? lastUpdate = null; + + if (_fileSystem.FileExists(path)) + { + lastUpdate = _fileSystem.GetLastWriteTimeUtc(path); + } + + var requestOptions = new HttpRequestOptions + { + Url = "http://emby.media/community/index.php?/blog/rss/1-media-browser-developers-blog", + Progress = new Progress(), + UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36", + BufferContent = false + }; + + using (var stream = await _httpClient.Get(requestOptions).ConfigureAwait(false)) + { + using (var reader = XmlReader.Create(stream)) + { + var news = ParseRssItems(reader).ToList(); + + _json.SerializeToFile(news, path); + + await CreateNotifications(news, lastUpdate, CancellationToken.None).ConfigureAwait(false); + } + } + } + + private Task CreateNotifications(List items, DateTime? lastUpdate, CancellationToken cancellationToken) + { + if (lastUpdate.HasValue) + { + items = items.Where(i => i.Date.ToUniversalTime() >= lastUpdate.Value) + .ToList(); + } + + var tasks = items.Select(i => _notifications.SendNotification(new NotificationRequest + { + Date = i.Date, + Name = i.Title, + Description = i.Description, + Url = i.Link, + UserIds = _userManager.Users.Select(u => u.Id.ToString("N")).ToList() + + }, cancellationToken)); + + return Task.WhenAll(tasks); + } + + private IEnumerable ParseRssItems(XmlReader reader) + { + reader.MoveToContent(); + reader.Read(); + + while (!reader.EOF) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "channel": + { + using (var subReader = reader.ReadSubtree()) + { + return ParseFromChannelNode(subReader); + } + } + default: + { + reader.Skip(); + break; + } + } + } + else + { + reader.Read(); + } + } + + return new List(); + } + + private IEnumerable ParseFromChannelNode(XmlReader reader) + { + var list = new List(); + + reader.MoveToContent(); + reader.Read(); + + while (!reader.EOF) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "item": + { + using (var subReader = reader.ReadSubtree()) + { + list.Add(ParseItem(subReader)); + } + break; + } + default: + { + reader.Skip(); + break; + } + } + } + else + { + reader.Read(); + } + } + + return list; + } + + private NewsItem ParseItem(XmlReader reader) + { + var item = new NewsItem(); + + reader.MoveToContent(); + reader.Read(); + + while (!reader.EOF) + { + if (reader.NodeType == XmlNodeType.Element) + { + switch (reader.Name) + { + case "title": + { + item.Title = reader.ReadElementContentAsString(); + break; + } + case "link": + { + item.Link = reader.ReadElementContentAsString(); + break; + } + case "description": + { + item.DescriptionHtml = reader.ReadElementContentAsString(); + item.Description = item.DescriptionHtml.StripHtml(); + break; + } + case "pubDate": + { + var date = reader.ReadElementContentAsString(); + DateTime parsedDate; + + if (DateTime.TryParse(date, out parsedDate)) + { + item.Date = parsedDate; + } + break; + } + default: + { + reader.Skip(); + break; + } + } + } + else + { + reader.Read(); + } + } + + return item; + } + + public void Dispose() + { + if (_timer != null) + { + _timer.Dispose(); + _timer = null; + } + } + } +} diff --git a/Emby.Server.Implementations/project.json b/Emby.Server.Implementations/project.json index b1373cd456..81f816753c 100644 --- a/Emby.Server.Implementations/project.json +++ b/Emby.Server.Implementations/project.json @@ -1,8 +1,7 @@ -{ +{ "supports": {}, "dependencies": { - "MediaBrowser.Naming": "1.0.0.59", - "Patterns.Logging": "1.0.0.6" + "MediaBrowser.Naming": "1.0.0.59" }, "frameworks": { ".NETPortable,Version=v4.5,Profile=Profile7": {} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs deleted file mode 100644 index 1067e052d9..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/AutomaticRestartEntryPoint.cs +++ /dev/null @@ -1,121 +0,0 @@ -using MediaBrowser.Controller; -using MediaBrowser.Controller.Configuration; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Tasks; -using System; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Model.LiveTv; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - public class AutomaticRestartEntryPoint : IServerEntryPoint - { - private readonly IServerApplicationHost _appHost; - private readonly ILogger _logger; - private readonly ITaskManager _iTaskManager; - private readonly ISessionManager _sessionManager; - private readonly IServerConfigurationManager _config; - private readonly ILiveTvManager _liveTvManager; - - private Timer _timer; - - public AutomaticRestartEntryPoint(IServerApplicationHost appHost, ILogger logger, ITaskManager iTaskManager, ISessionManager sessionManager, IServerConfigurationManager config, ILiveTvManager liveTvManager) - { - _appHost = appHost; - _logger = logger; - _iTaskManager = iTaskManager; - _sessionManager = sessionManager; - _config = config; - _liveTvManager = liveTvManager; - } - - public void Run() - { - if (_appHost.CanSelfRestart) - { - _appHost.HasPendingRestartChanged += _appHost_HasPendingRestartChanged; - } - } - - void _appHost_HasPendingRestartChanged(object sender, EventArgs e) - { - DisposeTimer(); - - if (_appHost.HasPendingRestart) - { - _timer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(10), TimeSpan.FromMinutes(10)); - } - } - - private async void TimerCallback(object state) - { - if (_config.Configuration.EnableAutomaticRestart) - { - var isIdle = await IsIdle().ConfigureAwait(false); - - if (isIdle) - { - DisposeTimer(); - - try - { - _appHost.Restart(); - } - catch (Exception ex) - { - _logger.ErrorException("Error restarting server", ex); - } - } - } - } - - private async Task IsIdle() - { - if (_iTaskManager.ScheduledTasks.Any(i => i.State != TaskState.Idle)) - { - return false; - } - - if (_liveTvManager.Services.Count == 1) - { - try - { - var timers = await _liveTvManager.GetTimers(new TimerQuery(), CancellationToken.None).ConfigureAwait(false); - if (timers.Items.Any(i => i.Status == RecordingStatus.InProgress)) - { - return false; - } - } - catch (Exception ex) - { - _logger.ErrorException("Error getting timers", ex); - } - } - - var now = DateTime.UtcNow; - - return !_sessionManager.Sessions.Any(i => (now - i.LastActivityDate).TotalMinutes < 30); - } - - public void Dispose() - { - _appHost.HasPendingRestartChanged -= _appHost_HasPendingRestartChanged; - - DisposeTimer(); - } - - private void DisposeTimer() - { - if (_timer != null) - { - _timer.Dispose(); - _timer = null; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs deleted file mode 100644 index 9f06a9860d..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs +++ /dev/null @@ -1,340 +0,0 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Model.Extensions; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - public class LibraryChangedNotifier : IServerEntryPoint - { - /// - /// The _library manager - /// - private readonly ILibraryManager _libraryManager; - - private readonly ISessionManager _sessionManager; - private readonly IUserManager _userManager; - private readonly ILogger _logger; - - /// - /// The _library changed sync lock - /// - private readonly object _libraryChangedSyncLock = new object(); - - private readonly List _foldersAddedTo = new List(); - private readonly List _foldersRemovedFrom = new List(); - - private readonly List _itemsAdded = new List(); - private readonly List _itemsRemoved = new List(); - private readonly List _itemsUpdated = new List(); - - /// - /// Gets or sets the library update timer. - /// - /// The library update timer. - private Timer LibraryUpdateTimer { get; set; } - - /// - /// The library update duration - /// - private const int LibraryUpdateDuration = 5000; - - public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IUserManager userManager, ILogger logger) - { - _libraryManager = libraryManager; - _sessionManager = sessionManager; - _userManager = userManager; - _logger = logger; - } - - public void Run() - { - _libraryManager.ItemAdded += libraryManager_ItemAdded; - _libraryManager.ItemUpdated += libraryManager_ItemUpdated; - _libraryManager.ItemRemoved += libraryManager_ItemRemoved; - - } - - /// - /// Handles the ItemAdded event of the libraryManager control. - /// - /// The source of the event. - /// The instance containing the event data. - void libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) - { - if (!FilterItem(e.Item)) - { - return; - } - - lock (_libraryChangedSyncLock) - { - if (LibraryUpdateTimer == null) - { - LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, - Timeout.Infinite); - } - else - { - LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); - } - - if (e.Item.Parent != null) - { - _foldersAddedTo.Add(e.Item.Parent); - } - - _itemsAdded.Add(e.Item); - } - } - - /// - /// Handles the ItemUpdated event of the libraryManager control. - /// - /// The source of the event. - /// The instance containing the event data. - void libraryManager_ItemUpdated(object sender, ItemChangeEventArgs e) - { - if (!FilterItem(e.Item)) - { - return; - } - - lock (_libraryChangedSyncLock) - { - if (LibraryUpdateTimer == null) - { - LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, - Timeout.Infinite); - } - else - { - LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); - } - - _itemsUpdated.Add(e.Item); - } - } - - /// - /// Handles the ItemRemoved event of the libraryManager control. - /// - /// The source of the event. - /// The instance containing the event data. - void libraryManager_ItemRemoved(object sender, ItemChangeEventArgs e) - { - if (!FilterItem(e.Item)) - { - return; - } - - lock (_libraryChangedSyncLock) - { - if (LibraryUpdateTimer == null) - { - LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, - Timeout.Infinite); - } - else - { - LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); - } - - if (e.Item.Parent != null) - { - _foldersRemovedFrom.Add(e.Item.Parent); - } - - _itemsRemoved.Add(e.Item); - } - } - - /// - /// Libraries the update timer callback. - /// - /// The state. - private void LibraryUpdateTimerCallback(object state) - { - lock (_libraryChangedSyncLock) - { - // Remove dupes in case some were saved multiple times - var foldersAddedTo = _foldersAddedTo.DistinctBy(i => i.Id).ToList(); - - var foldersRemovedFrom = _foldersRemovedFrom.DistinctBy(i => i.Id).ToList(); - - var itemsUpdated = _itemsUpdated - .Where(i => !_itemsAdded.Contains(i)) - .DistinctBy(i => i.Id) - .ToList(); - - SendChangeNotifications(_itemsAdded.ToList(), itemsUpdated, _itemsRemoved.ToList(), foldersAddedTo, foldersRemovedFrom, CancellationToken.None); - - if (LibraryUpdateTimer != null) - { - LibraryUpdateTimer.Dispose(); - LibraryUpdateTimer = null; - } - - _itemsAdded.Clear(); - _itemsRemoved.Clear(); - _itemsUpdated.Clear(); - _foldersAddedTo.Clear(); - _foldersRemovedFrom.Clear(); - } - } - - /// - /// Sends the change notifications. - /// - /// The items added. - /// The items updated. - /// The items removed. - /// The folders added to. - /// The folders removed from. - /// The cancellation token. - private async void SendChangeNotifications(List itemsAdded, List itemsUpdated, List itemsRemoved, List foldersAddedTo, List foldersRemovedFrom, CancellationToken cancellationToken) - { - foreach (var user in _userManager.Users.ToList()) - { - var id = user.Id; - var userSessions = _sessionManager.Sessions - .Where(u => u.UserId.HasValue && u.UserId.Value == id && u.SessionController != null && u.IsActive) - .ToList(); - - if (userSessions.Count > 0) - { - 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); - } - } - } - - } - } - - /// - /// Gets the library update info. - /// - /// The items added. - /// The items updated. - /// The items removed. - /// The folders added to. - /// The folders removed from. - /// The user id. - /// LibraryUpdateInfo. - private LibraryUpdateInfo GetLibraryUpdateInfo(IEnumerable itemsAdded, IEnumerable itemsUpdated, IEnumerable itemsRemoved, IEnumerable foldersAddedTo, IEnumerable foldersRemovedFrom, Guid userId) - { - var user = _userManager.GetUserById(userId); - - return new LibraryUpdateInfo - { - ItemsAdded = itemsAdded.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), - - ItemsUpdated = itemsUpdated.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), - - ItemsRemoved = itemsRemoved.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user, true)).Select(i => i.Id.ToString("N")).Distinct().ToList(), - - FoldersAddedTo = foldersAddedTo.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList(), - - FoldersRemovedFrom = foldersRemovedFrom.SelectMany(i => TranslatePhysicalItemToUserLibrary(i, user)).Select(i => i.Id.ToString("N")).Distinct().ToList() - }; - } - - private bool FilterItem(BaseItem item) - { - if (!item.IsFolder && item.LocationType == LocationType.Virtual) - { - return false; - } - - if (item is IItemByName && !(item is MusicArtist)) - { - return false; - } - - return item.SourceType == SourceType.Library; - } - - /// - /// Translates the physical item to user library. - /// - /// - /// The item. - /// The user. - /// if set to true [include if not found]. - /// IEnumerable{``0}. - private IEnumerable TranslatePhysicalItemToUserLibrary(T item, User user, bool includeIfNotFound = false) - where T : BaseItem - { - // If the physical root changed, return the user root - if (item is AggregateFolder) - { - return new[] { user.RootFolder as T }; - } - - // Return it only if it's in the user's library - if (includeIfNotFound || item.IsVisibleStandalone(user)) - { - return new[] { item }; - } - - return new T[] { }; - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - if (LibraryUpdateTimer != null) - { - LibraryUpdateTimer.Dispose(); - LibraryUpdateTimer = null; - } - - _libraryManager.ItemAdded -= libraryManager_ItemAdded; - _libraryManager.ItemUpdated -= libraryManager_ItemUpdated; - _libraryManager.ItemRemoved -= libraryManager_ItemRemoved; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs b/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs deleted file mode 100644 index 47f22cae6b..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/LoadRegistrations.cs +++ /dev/null @@ -1,71 +0,0 @@ -using MediaBrowser.Common.Security; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.Logging; -using System; -using System.Threading.Tasks; -using MediaBrowser.Server.Implementations.Threading; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - /// - /// Class LoadRegistrations - /// - public class LoadRegistrations : IServerEntryPoint - { - /// - /// The _security manager - /// - private readonly ISecurityManager _securityManager; - - /// - /// The _logger - /// - private readonly ILogger _logger; - - private PeriodicTimer _timer; - - /// - /// Initializes a new instance of the class. - /// - /// The security manager. - /// The log manager. - public LoadRegistrations(ISecurityManager securityManager, ILogManager logManager) - { - _securityManager = securityManager; - - _logger = logManager.GetLogger("Registration Loader"); - } - - /// - /// Runs this instance. - /// - public void Run() - { - _timer = new PeriodicTimer(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); - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - if (_timer != null) - { - _timer.Dispose(); - _timer = null; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs deleted file mode 100644 index 414fda400b..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/RecordingNotifier.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - public class RecordingNotifier : IServerEntryPoint - { - private readonly ILiveTvManager _liveTvManager; - private readonly ISessionManager _sessionManager; - private readonly IUserManager _userManager; - private readonly ILogger _logger; - - public RecordingNotifier(ISessionManager sessionManager, IUserManager userManager, ILogger logger, ILiveTvManager liveTvManager) - { - _sessionManager = sessionManager; - _userManager = userManager; - _logger = logger; - _liveTvManager = liveTvManager; - } - - public void Run() - { - _liveTvManager.TimerCancelled += _liveTvManager_TimerCancelled; - _liveTvManager.SeriesTimerCancelled += _liveTvManager_SeriesTimerCancelled; - _liveTvManager.TimerCreated += _liveTvManager_TimerCreated; - _liveTvManager.SeriesTimerCreated += _liveTvManager_SeriesTimerCreated; - } - - private void _liveTvManager_SeriesTimerCreated(object sender, Model.Events.GenericEventArgs e) - { - SendMessage("SeriesTimerCreated", e.Argument); - } - - private void _liveTvManager_TimerCreated(object sender, Model.Events.GenericEventArgs e) - { - SendMessage("TimerCreated", e.Argument); - } - - private void _liveTvManager_SeriesTimerCancelled(object sender, Model.Events.GenericEventArgs e) - { - SendMessage("SeriesTimerCancelled", e.Argument); - } - - private void _liveTvManager_TimerCancelled(object sender, Model.Events.GenericEventArgs e) - { - SendMessage("TimerCancelled", e.Argument); - } - - private async void SendMessage(string name, TimerEventInfo info) - { - var users = _userManager.Users.Where(i => i.Policy.EnableLiveTvAccess).Select(i => i.Id.ToString("N")).ToList(); - - try - { - await _sessionManager.SendMessageToUserSessions(users, name, info, CancellationToken.None); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending message", ex); - } - } - - public void Dispose() - { - _liveTvManager.TimerCancelled -= _liveTvManager_TimerCancelled; - _liveTvManager.SeriesTimerCancelled -= _liveTvManager_SeriesTimerCancelled; - _liveTvManager.TimerCreated -= _liveTvManager_TimerCreated; - _liveTvManager.SeriesTimerCreated -= _liveTvManager_SeriesTimerCreated; - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs b/MediaBrowser.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs deleted file mode 100644 index a0b7ff515c..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs +++ /dev/null @@ -1,41 +0,0 @@ -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; -using System.Threading; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - /// - /// Class RefreshUsersMetadata - /// - public class RefreshUsersMetadata : IServerEntryPoint - { - /// - /// The _user manager - /// - private readonly IUserManager _userManager; - - /// - /// Initializes a new instance of the class. - /// - /// The user manager. - public RefreshUsersMetadata(IUserManager userManager) - { - _userManager = userManager; - } - - /// - /// Runs this instance. - /// - public async void Run() - { - await _userManager.RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs deleted file mode 100644 index 0da48a2d88..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/ServerEventNotifier.cs +++ /dev/null @@ -1,203 +0,0 @@ -using MediaBrowser.Common.Plugins; -using MediaBrowser.Common.Updates; -using MediaBrowser.Controller; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Net; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Controller.Sync; -using MediaBrowser.Model.Events; -using MediaBrowser.Model.Sync; -using System; -using System.Collections.Generic; -using System.Threading; -using MediaBrowser.Model.Tasks; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - /// - /// Class WebSocketEvents - /// - public class ServerEventNotifier : IServerEntryPoint - { - /// - /// The _server manager - /// - private readonly IServerManager _serverManager; - - /// - /// The _user manager - /// - private readonly IUserManager _userManager; - - /// - /// The _installation manager - /// - private readonly IInstallationManager _installationManager; - - /// - /// The _kernel - /// - private readonly IServerApplicationHost _appHost; - - /// - /// The _task manager - /// - 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) - { - _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.UserConfigurationUpdated += _userManager_UserConfigurationUpdated; - - _appHost.HasPendingRestartChanged += kernel_HasPendingRestartChanged; - - _installationManager.PluginUninstalled += InstallationManager_PluginUninstalled; - _installationManager.PackageInstalling += _installationManager_PackageInstalling; - _installationManager.PackageInstallationCancelled += _installationManager_PackageInstallationCancelled; - _installationManager.PackageInstallationCompleted += _installationManager_PackageInstallationCompleted; - _installationManager.PackageInstallationFailed += _installationManager_PackageInstallationFailed; - - _taskManager.TaskCompleted += _taskManager_TaskCompleted; - _syncManager.SyncJobCreated += _syncManager_SyncJobCreated; - _syncManager.SyncJobCancelled += _syncManager_SyncJobCancelled; - } - - void _syncManager_SyncJobCancelled(object sender, GenericEventArgs e) - { - _sessionManager.SendMessageToUserDeviceSessions(e.Argument.TargetId, "SyncJobCancelled", e.Argument, CancellationToken.None); - } - - void _syncManager_SyncJobCreated(object sender, GenericEventArgs e) - { - _sessionManager.SendMessageToUserDeviceSessions(e.Argument.Job.TargetId, "SyncJobCreated", e.Argument, CancellationToken.None); - } - - void _installationManager_PackageInstalling(object sender, InstallationEventArgs e) - { - _serverManager.SendWebSocketMessage("PackageInstalling", e.InstallationInfo); - } - - void _installationManager_PackageInstallationCancelled(object sender, InstallationEventArgs e) - { - _serverManager.SendWebSocketMessage("PackageInstallationCancelled", e.InstallationInfo); - } - - void _installationManager_PackageInstallationCompleted(object sender, InstallationEventArgs e) - { - _serverManager.SendWebSocketMessage("PackageInstallationCompleted", e.InstallationInfo); - } - - void _installationManager_PackageInstallationFailed(object sender, InstallationFailedEventArgs e) - { - _serverManager.SendWebSocketMessage("PackageInstallationFailed", e.InstallationInfo); - } - - void _taskManager_TaskCompleted(object sender, TaskCompletionEventArgs e) - { - _serverManager.SendWebSocketMessage("ScheduledTaskEnded", e.Result); - } - - /// - /// Installations the manager_ plugin uninstalled. - /// - /// The sender. - /// The e. - void InstallationManager_PluginUninstalled(object sender, GenericEventArgs e) - { - _serverManager.SendWebSocketMessage("PluginUninstalled", e.Argument.GetPluginInfo()); - } - - /// - /// Handles the HasPendingRestartChanged event of the kernel control. - /// - /// The source of the event. - /// The instance containing the event data. - void kernel_HasPendingRestartChanged(object sender, EventArgs e) - { - _sessionManager.SendRestartRequiredNotification(CancellationToken.None); - } - - /// - /// Users the manager_ user updated. - /// - /// The sender. - /// The e. - void userManager_UserUpdated(object sender, GenericEventArgs e) - { - var dto = _userManager.GetUserDto(e.Argument); - - SendMessageToUserSession(e.Argument, "UserUpdated", dto); - } - - /// - /// Users the manager_ user deleted. - /// - /// The sender. - /// The e. - void userManager_UserDeleted(object sender, GenericEventArgs e) - { - SendMessageToUserSession(e.Argument, "UserDeleted", e.Argument.Id.ToString("N")); - } - - void _userManager_UserConfigurationUpdated(object sender, GenericEventArgs e) - { - var dto = _userManager.GetUserDto(e.Argument); - - SendMessageToUserSession(e.Argument, "UserConfigurationUpdated", dto); - } - - private async void SendMessageToUserSession(User user, string name, T data) - { - await _sessionManager.SendMessageToUserSessions(new List { user.Id.ToString("N") }, name, data, CancellationToken.None); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - if (dispose) - { - _userManager.UserDeleted -= userManager_UserDeleted; - _userManager.UserUpdated -= userManager_UserUpdated; - _userManager.UserConfigurationUpdated -= _userManager_UserConfigurationUpdated; - - _installationManager.PluginUninstalled -= InstallationManager_PluginUninstalled; - _installationManager.PackageInstalling -= _installationManager_PackageInstalling; - _installationManager.PackageInstallationCancelled -= _installationManager_PackageInstallationCancelled; - _installationManager.PackageInstallationCompleted -= _installationManager_PackageInstallationCompleted; - _installationManager.PackageInstallationFailed -= _installationManager_PackageInstallationFailed; - - _appHost.HasPendingRestartChanged -= kernel_HasPendingRestartChanged; - _syncManager.SyncJobCreated -= _syncManager_SyncJobCreated; - _syncManager.SyncJobCancelled -= _syncManager_SyncJobCancelled; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs deleted file mode 100644 index d14bd43689..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageEntryPoint.cs +++ /dev/null @@ -1,133 +0,0 @@ -using MediaBrowser.Common; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Library; -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; -using System.Threading.Tasks; -using MediaBrowser.Controller.Configuration; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - /// - /// Class UsageEntryPoint - /// - public class UsageEntryPoint : IServerEntryPoint - { - private readonly IApplicationHost _applicationHost; - private readonly IHttpClient _httpClient; - private readonly ILogger _logger; - private readonly ISessionManager _sessionManager; - private readonly IUserManager _userManager; - private readonly IServerConfigurationManager _config; - - private readonly ConcurrentDictionary _apps = new ConcurrentDictionary(); - - public UsageEntryPoint(ILogger logger, IApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config) - { - _logger = logger; - _applicationHost = applicationHost; - _httpClient = httpClient; - _sessionManager = sessionManager; - _userManager = userManager; - _config = config; - - _sessionManager.SessionStarted += _sessionManager_SessionStarted; - } - - void _sessionManager_SessionStarted(object sender, SessionEventArgs e) - { - var session = e.SessionInfo; - - if (!string.IsNullOrEmpty(session.Client) && - !string.IsNullOrEmpty(session.DeviceName) && - !string.IsNullOrEmpty(session.DeviceId) && - !string.IsNullOrEmpty(session.ApplicationVersion)) - { - var keys = new List - { - session.Client, - session.DeviceName, - session.DeviceId, - session.ApplicationVersion - }; - - var key = string.Join("_", keys.ToArray()).GetMD5(); - - _apps.GetOrAdd(key, guid => GetNewClientInfo(session)); - } - } - - private async void ReportNewSession(ClientInfo client) - { - if (!_config.Configuration.EnableAnonymousUsageReporting) - { - return; - } - - try - { - await new UsageReporter(_applicationHost, _httpClient, _userManager, _logger) - .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, - DeviceName = session.DeviceName, - DeviceId = session.DeviceId - }; - - ReportNewSession(info); - - return info; - } - - public async void Run() - { - await Task.Delay(5000).ConfigureAwait(false); - OnTimerFired(); - } - - /// - /// Called when [timer fired]. - /// - private async void OnTimerFired() - { - if (!_config.Configuration.EnableAnonymousUsageReporting) - { - return; - } - - try - { - await new UsageReporter(_applicationHost, _httpClient, _userManager, _logger) - .ReportServerUsage(CancellationToken.None) - .ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending anonymous usage statistics.", ex); - } - } - - public void Dispose() - { - _sessionManager.SessionStarted -= _sessionManager_SessionStarted; - } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs deleted file mode 100644 index e445300e4d..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs +++ /dev/null @@ -1,138 +0,0 @@ -using MediaBrowser.Common; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Connect; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.Logging; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - public class UsageReporter - { - private readonly IApplicationHost _applicationHost; - private readonly IHttpClient _httpClient; - private readonly IUserManager _userManager; - private readonly ILogger _logger; - private const string MbAdminUrl = "https://www.mb3admin.com/admin/"; - - public UsageReporter(IApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger) - { - _applicationHost = applicationHost; - _httpClient = httpClient; - _userManager = userManager; - _logger = logger; - } - - public async Task ReportServerUsage(CancellationToken cancellationToken) - { - cancellationToken.ThrowIfCancellationRequested(); - - var data = new Dictionary - { - { "feature", _applicationHost.Name }, - { "mac", _applicationHost.SystemId }, - { "serverid", _applicationHost.SystemId }, - { "deviceid", _applicationHost.SystemId }, - { "ver", _applicationHost.ApplicationVersion.ToString() }, - { "platform", _applicationHost.OperatingSystemDisplayName }, - { "isservice", _applicationHost.IsRunningAsService.ToString().ToLower()} - }; - - var users = _userManager.Users.ToList(); - - data["localusers"] = users.Count(i => !i.ConnectLinkType.HasValue).ToString(CultureInfo.InvariantCulture); - data["guests"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest).ToString(CultureInfo.InvariantCulture); - data["linkedusers"] = users.Count(i => i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.LinkedUser).ToString(CultureInfo.InvariantCulture); - - data["plugins"] = string.Join(",", _applicationHost.Plugins.Select(i => i.Id).ToArray()); - - var logErrors = false; -#if DEBUG - logErrors = true; -#endif - var options = new HttpRequestOptions - { - Url = MbAdminUrl + "service/registration/ping", - CancellationToken = cancellationToken, - - // Seeing block length errors - EnableHttpCompression = false, - - LogRequest = false, - LogErrors = logErrors, - BufferContent = false - }; - - options.SetPostData(data); - - using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) - { - - } - } - - public async Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken) - { - if (string.IsNullOrWhiteSpace(app.DeviceId)) - { - throw new ArgumentException("Client info must have a device Id"); - } - - _logger.Info("App Activity: app: {0}, version: {1}, deviceId: {2}, deviceName: {3}", - app.AppName ?? "Unknown App", - app.AppVersion ?? "Unknown", - app.DeviceId, - app.DeviceName ?? "Unknown"); - - cancellationToken.ThrowIfCancellationRequested(); - - var data = new Dictionary - { - { "feature", app.AppName ?? "Unknown App" }, - { "serverid", _applicationHost.SystemId }, - { "deviceid", app.DeviceId }, - { "mac", app.DeviceId }, - { "ver", app.AppVersion ?? "Unknown" }, - { "platform", app.DeviceName }, - }; - - var logErrors = false; - -#if DEBUG - logErrors = true; -#endif - var options = new HttpRequestOptions - { - Url = MbAdminUrl + "service/registration/ping", - CancellationToken = cancellationToken, - - // Seeing block length errors - EnableHttpCompression = false, - - LogRequest = false, - LogErrors = logErrors, - BufferContent = false - }; - - options.SetPostData(data); - - using (var response = await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)) - { - - } - } - } - - public class ClientInfo - { - public string AppName { get; set; } - public string AppVersion { get; set; } - public string DeviceName { get; set; } - public string DeviceId { get; set; } - } -} diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs deleted file mode 100644 index 8262048b1d..0000000000 --- a/MediaBrowser.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs +++ /dev/null @@ -1,162 +0,0 @@ -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Controller.Session; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Session; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Model.Extensions; - -namespace MediaBrowser.Server.Implementations.EntryPoints -{ - class UserDataChangeNotifier : IServerEntryPoint - { - private readonly ISessionManager _sessionManager; - private readonly ILogger _logger; - private readonly IUserDataManager _userDataManager; - private readonly IUserManager _userManager; - - private readonly object _syncLock = new object(); - private Timer UpdateTimer { get; set; } - private const int UpdateDuration = 500; - - private readonly Dictionary> _changedItems = new Dictionary>(); - - public UserDataChangeNotifier(IUserDataManager userDataManager, ISessionManager sessionManager, ILogger logger, IUserManager userManager) - { - _userDataManager = userDataManager; - _sessionManager = sessionManager; - _logger = logger; - _userManager = userManager; - } - - public void Run() - { - _userDataManager.UserDataSaved += _userDataManager_UserDataSaved; - } - - void _userDataManager_UserDataSaved(object sender, UserDataSaveEventArgs e) - { - if (e.SaveReason == UserDataSaveReason.PlaybackProgress) - { - return; - } - - lock (_syncLock) - { - if (UpdateTimer == null) - { - UpdateTimer = new Timer(UpdateTimerCallback, null, UpdateDuration, - Timeout.Infinite); - } - else - { - UpdateTimer.Change(UpdateDuration, Timeout.Infinite); - } - - List keys; - - if (!_changedItems.TryGetValue(e.UserId, out keys)) - { - keys = new List(); - _changedItems[e.UserId] = keys; - } - - keys.Add(e.Item); - - var baseItem = e.Item as BaseItem; - - // Go up one level for indicators - if (baseItem != null) - { - var parent = baseItem.GetParent(); - - if (parent != null) - { - keys.Add(parent); - } - } - } - } - - private void UpdateTimerCallback(object state) - { - lock (_syncLock) - { - // Remove dupes in case some were saved multiple times - var changes = _changedItems.ToList(); - _changedItems.Clear(); - - var task = SendNotifications(changes, CancellationToken.None); - - if (UpdateTimer != null) - { - UpdateTimer.Dispose(); - UpdateTimer = null; - } - } - } - - private async Task SendNotifications(IEnumerable>> 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).Result; - dto.ItemId = i.Id.ToString("N"); - return dto; - }) - .ToList(); - - 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); - } - } - } - - } - } - - public void Dispose() - { - if (UpdateTimer != null) - { - UpdateTimer.Dispose(); - UpdateTimer = null; - } - - _userDataManager.UserDataSaved -= _userDataManager_UserDataSaved; - } - } -} diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 88e9478df3..b31c8286cd 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -46,17 +46,13 @@ ..\ThirdParty\emby\Emby.Common.Implementations.dll - ..\packages\Emby.XmlTv.1.0.0.62\lib\portable-net45+win8\Emby.XmlTv.dll + ..\packages\Emby.XmlTv.1.0.0.63\lib\portable-net45+win8\Emby.XmlTv.dll True ..\packages\ini-parser.2.3.0\lib\net20\INIFileParser.dll True - - ..\packages\MediaBrowser.Naming.1.0.0.59\lib\portable-net45+win8\MediaBrowser.Naming.dll - True - ..\packages\Microsoft.IO.RecyclableMemoryStream.1.1.0.0\lib\net45\Microsoft.IO.RecyclableMemoryStream.dll True @@ -120,17 +116,8 @@ - - - - - - - - - @@ -211,8 +198,6 @@ - - @@ -286,23 +271,6 @@ MediaBrowser.Providers - - - - - - - - - - - - - - - - - swagger-ui\lib\backbone-min.js @@ -368,7 +336,6 @@ swagger-ui\swagger-ui.min.js PreserveNewest - swagger-ui\fonts\droid-sans-v6-latin-700.eot PreserveNewest @@ -401,46 +368,25 @@ swagger-ui\fonts\droid-sans-v6-latin-regular.woff2 PreserveNewest + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -610,12 +556,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - swagger-ui\css\reset.css @@ -665,8 +648,6 @@ swagger-ui\lib\shred\content.js PreserveNewest - - diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs deleted file mode 100644 index 9f1744cc90..0000000000 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ /dev/null @@ -1,236 +0,0 @@ -using MediaBrowser.Controller.Chapters; -using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Movies; -using MediaBrowser.Controller.Entities.TV; -using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.MediaInfo; -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Controller.Library; - -namespace MediaBrowser.Server.Implementations.MediaEncoder -{ - public class EncodingManager : IEncodingManager - { - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - private readonly IMediaEncoder _encoder; - private readonly IChapterManager _chapterManager; - private readonly ILibraryManager _libraryManager; - - public EncodingManager(IFileSystem fileSystem, - ILogger logger, - IMediaEncoder encoder, - IChapterManager chapterManager, ILibraryManager libraryManager) - { - _fileSystem = fileSystem; - _logger = logger; - _encoder = encoder; - _chapterManager = chapterManager; - _libraryManager = libraryManager; - } - - /// - /// Gets the chapter images data path. - /// - /// The chapter images data path. - private string GetChapterImagesPath(IHasImages item) - { - return Path.Combine(item.GetInternalMetadataPath(), "chapters"); - } - - /// - /// Determines whether [is eligible for chapter image extraction] [the specified video]. - /// - /// The video. - /// true if [is eligible for chapter image extraction] [the specified video]; otherwise, false. - private bool IsEligibleForChapterImageExtraction(Video video) - { - if (video.IsPlaceHolder) - { - return false; - } - - var libraryOptions = _libraryManager.GetLibraryOptions(video); - if (libraryOptions != null) - { - if (!libraryOptions.EnableChapterImageExtraction) - { - return false; - } - } - else - { - return false; - } - - // Can't extract images if there are no video streams - return video.DefaultVideoStreamIndex.HasValue; - } - - /// - /// The first chapter ticks - /// - private static readonly long FirstChapterTicks = TimeSpan.FromSeconds(15).Ticks; - - public async Task RefreshChapterImages(ChapterImageRefreshOptions options, CancellationToken cancellationToken) - { - var extractImages = options.ExtractImages; - var video = options.Video; - var chapters = options.Chapters; - var saveChapters = options.SaveChapters; - - if (!IsEligibleForChapterImageExtraction(video)) - { - extractImages = false; - } - - var success = true; - var changesMade = false; - - var runtimeTicks = video.RunTimeTicks ?? 0; - - var currentImages = GetSavedChapterImages(video); - - foreach (var chapter in chapters) - { - if (chapter.StartPositionTicks >= runtimeTicks) - { - _logger.Info("Stopping chapter extraction for {0} because a chapter was found with a position greater than the runtime.", video.Name); - break; - } - - var path = GetChapterImagePath(video, chapter.StartPositionTicks); - - if (!currentImages.Contains(path, StringComparer.OrdinalIgnoreCase)) - { - if (extractImages) - { - if (video.VideoType == VideoType.HdDvd || video.VideoType == VideoType.Iso) - { - continue; - } - if (video.VideoType == VideoType.BluRay || video.VideoType == VideoType.Dvd) - { - if (video.PlayableStreamFileNames.Count != 1) - { - continue; - } - } - - try - { - // Add some time for the first chapter to make sure we don't end up with a black image - var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks); - - var protocol = MediaProtocol.File; - - var inputPath = MediaEncoderHelpers.GetInputArgument(_fileSystem, video.Path, protocol, null, video.PlayableStreamFileNames); - - _fileSystem.CreateDirectory(Path.GetDirectoryName(path)); - - var container = video.Container; - - var tempFile = await _encoder.ExtractVideoImage(inputPath, container, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false); - File.Copy(tempFile, path, true); - - try - { - File.Delete(tempFile); - } - catch - { - - } - - chapter.ImagePath = path; - chapter.ImageDateModified = _fileSystem.GetLastWriteTimeUtc(path); - changesMade = true; - } - catch (Exception ex) - { - _logger.ErrorException("Error extracting chapter images for {0}", ex, string.Join(",", video.Path)); - success = false; - break; - } - } - else if (!string.IsNullOrEmpty(chapter.ImagePath)) - { - chapter.ImagePath = null; - changesMade = true; - } - } - else if (!string.Equals(path, chapter.ImagePath, StringComparison.OrdinalIgnoreCase)) - { - chapter.ImagePath = path; - chapter.ImageDateModified = _fileSystem.GetLastWriteTimeUtc(path); - changesMade = true; - } - } - - if (saveChapters && changesMade) - { - await _chapterManager.SaveChapters(video.Id.ToString(), chapters, cancellationToken).ConfigureAwait(false); - } - - DeleteDeadImages(currentImages, chapters); - - return success; - } - - private string GetChapterImagePath(Video video, long chapterPositionTicks) - { - var filename = video.DateModified.Ticks.ToString(_usCulture) + "_" + chapterPositionTicks.ToString(_usCulture) + ".jpg"; - - return Path.Combine(GetChapterImagesPath(video), filename); - } - - private List GetSavedChapterImages(Video video) - { - var path = GetChapterImagesPath(video); - - try - { - return _fileSystem.GetFilePaths(path) - .ToList(); - } - catch (DirectoryNotFoundException) - { - return new List(); - } - } - - private void DeleteDeadImages(IEnumerable images, IEnumerable chapters) - { - var deadImages = images - .Except(chapters.Select(i => i.ImagePath).Where(i => !string.IsNullOrEmpty(i)), StringComparer.OrdinalIgnoreCase) - .Where(i => BaseItem.SupportedImageExtensions.Contains(Path.GetExtension(i), StringComparer.OrdinalIgnoreCase)) - .ToList(); - - foreach (var image in deadImages) - { - _logger.Debug("Deleting dead chapter image {0}", image); - - try - { - _fileSystem.DeleteFile(image); - } - catch (IOException ex) - { - _logger.ErrorException("Error deleting {0}.", ex, image); - } - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs b/MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs deleted file mode 100644 index 22cb4e86ac..0000000000 --- a/MediaBrowser.Server.Implementations/News/NewsEntryPoint.cs +++ /dev/null @@ -1,170 +0,0 @@ -using MediaBrowser.Common.Configuration; -using MediaBrowser.Common.Extensions; -using MediaBrowser.Common.Net; -using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.Notifications; -using MediaBrowser.Controller.Plugins; -using MediaBrowser.Model.Logging; -using MediaBrowser.Model.News; -using MediaBrowser.Model.Notifications; -using MediaBrowser.Model.Serialization; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Xml; -using MediaBrowser.Common.IO; -using MediaBrowser.Controller.IO; -using MediaBrowser.Model.IO; -using MediaBrowser.Server.Implementations.Threading; - -namespace MediaBrowser.Server.Implementations.News -{ - public class NewsEntryPoint : IServerEntryPoint - { - private PeriodicTimer _timer; - private readonly IHttpClient _httpClient; - private readonly IApplicationPaths _appPaths; - private readonly IFileSystem _fileSystem; - private readonly ILogger _logger; - private readonly IJsonSerializer _json; - - private readonly INotificationManager _notifications; - private readonly IUserManager _userManager; - - private readonly TimeSpan _frequency = TimeSpan.FromHours(24); - - public NewsEntryPoint(IHttpClient httpClient, IApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger, IJsonSerializer json, INotificationManager notifications, IUserManager userManager) - { - _httpClient = httpClient; - _appPaths = appPaths; - _fileSystem = fileSystem; - _logger = logger; - _json = json; - _notifications = notifications; - _userManager = userManager; - } - - public void Run() - { - _timer = new PeriodicTimer(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency); - } - - /// - /// Called when [timer fired]. - /// - /// The state. - private async void OnTimerFired(object state) - { - var path = Path.Combine(_appPaths.CachePath, "news.json"); - - try - { - await DownloadNews(path).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error downloading news", ex); - } - } - - private async Task DownloadNews(string path) - { - DateTime? lastUpdate = null; - - if (_fileSystem.FileExists(path)) - { - lastUpdate = _fileSystem.GetLastWriteTimeUtc(path); - } - - var requestOptions = new HttpRequestOptions - { - Url = "http://emby.media/community/index.php?/blog/rss/1-media-browser-developers-blog", - Progress = new Progress(), - UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36", - BufferContent = false - }; - - using (var stream = await _httpClient.Get(requestOptions).ConfigureAwait(false)) - { - var doc = new XmlDocument(); - doc.Load(stream); - - var news = ParseRssItems(doc).ToList(); - - _json.SerializeToFile(news, path); - - await CreateNotifications(news, lastUpdate, CancellationToken.None).ConfigureAwait(false); - } - } - - private Task CreateNotifications(List items, DateTime? lastUpdate, CancellationToken cancellationToken) - { - if (lastUpdate.HasValue) - { - items = items.Where(i => i.Date.ToUniversalTime() >= lastUpdate.Value) - .ToList(); - } - - var tasks = items.Select(i => _notifications.SendNotification(new NotificationRequest - { - Date = i.Date, - Name = i.Title, - Description = i.Description, - Url = i.Link, - UserIds = _userManager.Users.Select(u => u.Id.ToString("N")).ToList() - - }, cancellationToken)); - - return Task.WhenAll(tasks); - } - - private IEnumerable ParseRssItems(XmlDocument xmlDoc) - { - var nodes = xmlDoc.SelectNodes("rss/channel/item"); - - if (nodes != null) - { - foreach (XmlNode node in nodes) - { - var newsItem = new NewsItem(); - - newsItem.Title = ParseDocElements(node, "title"); - - newsItem.DescriptionHtml = ParseDocElements(node, "description"); - newsItem.Description = newsItem.DescriptionHtml.StripHtml(); - - newsItem.Link = ParseDocElements(node, "link"); - - var date = ParseDocElements(node, "pubDate"); - DateTime parsedDate; - - if (DateTime.TryParse(date, out parsedDate)) - { - newsItem.Date = parsedDate; - } - - yield return newsItem; - } - } - } - - private string ParseDocElements(XmlNode parent, string xPath) - { - var node = parent.SelectSingleNode(xPath); - - return node != null ? node.InnerText : string.Empty; - } - - public void Dispose() - { - if (_timer != null) - { - _timer.Dispose(); - _timer = null; - } - } - } -} diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config index cdfb48abe6..5a43abe0f6 100644 --- a/MediaBrowser.Server.Implementations/packages.config +++ b/MediaBrowser.Server.Implementations/packages.config @@ -1,8 +1,7 @@  - + - diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs index 294e780cca..861d59908e 100644 --- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs +++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs @@ -59,7 +59,6 @@ using MediaBrowser.Server.Implementations.HttpServer.Security; using MediaBrowser.Server.Implementations.IO; using MediaBrowser.Server.Implementations.LiveTv; using MediaBrowser.Server.Implementations.Localization; -using MediaBrowser.Server.Implementations.MediaEncoder; using MediaBrowser.Server.Implementations.Notifications; using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Implementations.Security; @@ -107,6 +106,7 @@ using Emby.Server.Implementations.Devices; using Emby.Server.Implementations.Dto; using Emby.Server.Implementations.FileOrganization; using Emby.Server.Implementations.Library; +using Emby.Server.Implementations.MediaEncoder; using Emby.Server.Implementations.Notifications; using Emby.Server.Implementations.Persistence; using Emby.Server.Implementations.Playlists; diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj index c64f065d7e..6a84ee0c5a 100644 --- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj +++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj @@ -38,6 +38,10 @@ ..\ThirdParty\emby\Emby.Dlna.dll + + ..\packages\MediaBrowser.Naming.1.0.0.59\lib\portable-net45+win8\MediaBrowser.Naming.dll + True + False ..\packages\Mono.Posix.4.0.0.0\lib\net40\Mono.Posix.dll diff --git a/MediaBrowser.Server.Startup.Common/packages.config b/MediaBrowser.Server.Startup.Common/packages.config index aa11730c79..ea3d0e7f8d 100644 --- a/MediaBrowser.Server.Startup.Common/packages.config +++ b/MediaBrowser.Server.Startup.Common/packages.config @@ -1,5 +1,6 @@  + diff --git a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj index 0a86e96a50..e84fa8e653 100644 --- a/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj +++ b/MediaBrowser.XbmcMetadata/MediaBrowser.XbmcMetadata.csproj @@ -32,11 +32,6 @@ prompt 4 - - - ..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll - - Properties\SharedVersion.cs diff --git a/MediaBrowser.XbmcMetadata/packages.config b/MediaBrowser.XbmcMetadata/packages.config index 79ff26ec64..6b8deb9c96 100644 --- a/MediaBrowser.XbmcMetadata/packages.config +++ b/MediaBrowser.XbmcMetadata/packages.config @@ -1,4 +1,3 @@  - \ No newline at end of file -- cgit v1.2.3 From 8ef442c2e8f39307f72bc98d6c79a9b5f09e6d72 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Nov 2016 18:53:02 -0400 Subject: move classes --- Emby.Dlna/DlnaManager.cs | 6 +- .../Emby.Server.Implementations.csproj | 7 + .../ServerManager/ServerManager.cs | 353 +++++++++++++++++++++ .../ServerManager/WebSocketConnection.cs | 295 +++++++++++++++++ .../TV/SeriesPostScanTask.cs | 241 ++++++++++++++ Emby.Server.Implementations/project.json | 3 +- .../Connect/ConnectEntryPoint.cs | 10 +- .../EntryPoints/ExternalPortForwarding.cs | 10 +- .../MediaBrowser.Server.Implementations.csproj | 4 - .../ServerManager/ServerManager.cs | 353 --------------------- .../ServerManager/WebSocketConnection.cs | 292 ----------------- .../TV/SeriesPostScanTask.cs | 238 -------------- .../Threading/PeriodicTimer.cs | 72 ----- .../ApplicationHost.cs | 4 +- .../EntryPoints/KeepServerAwake.cs | 2 +- .../MediaBrowser.Server.Startup.Common.csproj | 1 + .../Threading/PeriodicTimer.cs | 72 +++++ 17 files changed, 990 insertions(+), 973 deletions(-) create mode 100644 Emby.Server.Implementations/ServerManager/ServerManager.cs create mode 100644 Emby.Server.Implementations/ServerManager/WebSocketConnection.cs create mode 100644 Emby.Server.Implementations/TV/SeriesPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs delete mode 100644 MediaBrowser.Server.Implementations/ServerManager/WebSocketConnection.cs delete mode 100644 MediaBrowser.Server.Implementations/TV/SeriesPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Threading/PeriodicTimer.cs create mode 100644 MediaBrowser.Server.Startup.Common/Threading/PeriodicTimer.cs (limited to 'MediaBrowser.Server.Implementations/EntryPoints') diff --git a/Emby.Dlna/DlnaManager.cs b/Emby.Dlna/DlnaManager.cs index c5798a5d1b..c348e658cc 100644 --- a/Emby.Dlna/DlnaManager.cs +++ b/Emby.Dlna/DlnaManager.cs @@ -560,17 +560,19 @@ namespace Emby.Dlna ? ImageFormat.Png : ImageFormat.Jpg; + var resource = GetType().Namespace + ".Images." + filename.ToLower(); + #if NET46 return new ImageStream { Format = format, - Stream = GetType().Assembly.GetManifestResourceStream("MediaBrowser.Dlna.Images." + filename.ToLower()) + Stream = GetType().Assembly.GetManifestResourceStream(resource) }; #elif NETSTANDARD1_6 return new ImageStream { Format = format, - Stream = GetType().GetTypeInfo().Assembly.GetManifestResourceStream("MediaBrowser.Dlna.Images." + filename.ToLower()) + Stream = GetType().GetTypeInfo().Assembly.GetManifestResourceStream(resource) }; #endif throw new NotImplementedException(); diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index 152a165e21..7829193c53 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -131,6 +131,8 @@ + + @@ -178,6 +180,7 @@ + @@ -197,6 +200,10 @@ {7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b} MediaBrowser.Model + + {442b5058-dcaf-4263-bb6a-f21e31120a1b} + MediaBrowser.Providers +