using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Notifications; using MediaBrowser.Controller.Plugins; using MediaBrowser.Model.Logging; 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 CommonIO; namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { public class RemoteNotifications : IServerEntryPoint { private const string Url = "http://www.mb3admin.com/admin/service/MB3ServerNotifications.json"; private Timer _timer; private readonly IHttpClient _httpClient; private readonly IApplicationPaths _appPaths; private readonly ILogger _logger; private readonly IJsonSerializer _json; private readonly IUserManager _userManager; private readonly IFileSystem _fileSystem; private readonly TimeSpan _frequency = TimeSpan.FromHours(6); private readonly TimeSpan _maxAge = TimeSpan.FromDays(31); private readonly INotificationManager _notificationManager; public RemoteNotifications(IApplicationPaths appPaths, ILogger logger, IHttpClient httpClient, IJsonSerializer json, IUserManager userManager, IFileSystem fileSystem, INotificationManager notificationManager) { _appPaths = appPaths; _logger = logger; _httpClient = httpClient; _json = json; _userManager = userManager; _fileSystem = fileSystem; _notificationManager = notificationManager; } /// /// Runs this instance. /// public void Run() { _timer = new Timer(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency); } /// /// Called when [timer fired]. /// /// The state. private async void OnTimerFired(object state) { var dataPath = Path.Combine(_appPaths.DataPath, "remotenotifications.json"); var lastRunTime = _fileSystem.FileExists(dataPath) ? _fileSystem.GetLastWriteTimeUtc(dataPath) : DateTime.MinValue; try { await DownloadNotifications(dataPath, lastRunTime).ConfigureAwait(false); } catch (Exception ex) { _logger.ErrorException("Error downloading remote notifications", ex); } } /// /// Downloads the notifications. /// /// The data path. /// The last run time. /// Task. private async Task DownloadNotifications(string dataPath, DateTime lastRunTime) { using (var stream = await _httpClient.Get(new HttpRequestOptions { Url = Url }).ConfigureAwait(false)) { var notifications = _json.DeserializeFromStream(stream); _fileSystem.WriteAllText(dataPath, string.Empty); await CreateNotifications(notifications, lastRunTime).ConfigureAwait(false); } } /// /// Creates the notifications. /// /// The notifications. /// The last run time. /// Task. private async Task CreateNotifications(IEnumerable notifications, DateTime lastRunTime) { // Only show notifications that are active, new since last download, and not older than max age var notificationList = notifications .Where(i => string.Equals(i.active, "1") && i.date.ToUniversalTime() > lastRunTime && (DateTime.UtcNow - i.date.ToUniversalTime()) <= _maxAge) .ToList(); var userIds = _userManager.Users.Select(i => i.Id.ToString("N")).ToList(); foreach (var notification in notificationList) { await _notificationManager.SendNotification(new NotificationRequest { Date = notification.date, Name = notification.name, Description = notification.description, Url = notification.url, UserIds = userIds }, CancellationToken.None).ConfigureAwait(false); } } public void Dispose() { if (_timer != null) { _timer.Dispose(); _timer = null; } } private class RemoteNotification { public string id { get; set; } public DateTime date { get; set; } public string name { get; set; } public string description { get; set; } public string category { get; set; } public string url { get; set; } public object imageUrl { get; set; } public string active { get; set; } } } }