using MediaBrowser.Common.Net; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Session; using MediaBrowser.Model.Entities; using System.Linq; using System.Threading; namespace MediaBrowser.ServerApplication.EntryPoints { public class LibraryChangedNotifier : IServerEntryPoint { /// /// The _library manager /// private readonly ILibraryManager _libraryManager; private readonly ISessionManager _sessionManager; private readonly IServerManager _serverManager; /// /// The _library changed sync lock /// private readonly object _libraryChangedSyncLock = new object(); /// /// Gets or sets the library update info. /// /// The library update info. private LibraryUpdateInfo LibraryUpdateInfo { get; set; } /// /// Gets or sets the library update timer. /// /// The library update timer. private Timer LibraryUpdateTimer { get; set; } /// /// The library update duration /// private const int LibraryUpdateDuration = 60000; public LibraryChangedNotifier(ILibraryManager libraryManager, ISessionManager sessionManager, IServerManager serverManager) { _libraryManager = libraryManager; _sessionManager = sessionManager; _serverManager = serverManager; } 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) { lock (_libraryChangedSyncLock) { if (LibraryUpdateInfo == null) { LibraryUpdateInfo = new LibraryUpdateInfo(); } if (LibraryUpdateTimer == null) { LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite); } else { LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); } if (e.Item.Parent != null) { LibraryUpdateInfo.FoldersAddedTo.Add(e.Item.Parent.Id); } LibraryUpdateInfo.ItemsAdded.Add(e.Item.Id); } } /// /// 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) { lock (_libraryChangedSyncLock) { if (LibraryUpdateInfo == null) { LibraryUpdateInfo = new LibraryUpdateInfo(); } if (LibraryUpdateTimer == null) { LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite); } else { LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); } LibraryUpdateInfo.ItemsUpdated.Add(e.Item.Id); } } /// /// 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) { lock (_libraryChangedSyncLock) { if (LibraryUpdateInfo == null) { LibraryUpdateInfo = new LibraryUpdateInfo(); } if (LibraryUpdateTimer == null) { LibraryUpdateTimer = new Timer(LibraryUpdateTimerCallback, null, LibraryUpdateDuration, Timeout.Infinite); } else { LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite); } if (e.Item.Parent != null) { LibraryUpdateInfo.FoldersRemovedFrom.Add(e.Item.Parent.Id); } LibraryUpdateInfo.ItemsRemoved.Add(e.Item.Id); } } /// /// Libraries the update timer callback. /// /// The state. private void LibraryUpdateTimerCallback(object state) { lock (_libraryChangedSyncLock) { // Remove dupes in case some were saved multiple times LibraryUpdateInfo.FoldersAddedTo = LibraryUpdateInfo.FoldersAddedTo.Distinct().ToList(); LibraryUpdateInfo.FoldersRemovedFrom = LibraryUpdateInfo.FoldersRemovedFrom.Distinct().ToList(); LibraryUpdateInfo.ItemsUpdated = LibraryUpdateInfo.ItemsUpdated .Where(i => !LibraryUpdateInfo.ItemsAdded.Contains(i)) .Distinct() .ToList(); _serverManager.SendWebSocketMessage("LibraryChanged", LibraryUpdateInfo); if (LibraryUpdateTimer != null) { LibraryUpdateTimer.Dispose(); LibraryUpdateTimer = null; } LibraryUpdateInfo = null; } } /// /// 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; } } } }