mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-04 03:27:21 -05:00 
			
		
		
		
	better caching of remote data
This commit is contained in:
		
							parent
							
								
									4bf13f7754
								
							
						
					
					
						commit
						821e824687
					
				@ -78,12 +78,6 @@ namespace MediaBrowser.Api.System
 | 
			
		||||
        public string Name { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Route("/System/SupporterInfo", "GET")]
 | 
			
		||||
    [Authenticated]
 | 
			
		||||
    public class GetSupporterInfo : IReturn<SupporterInfo>
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Class SystemInfoService
 | 
			
		||||
    /// </summary>
 | 
			
		||||
@ -116,13 +110,6 @@ namespace MediaBrowser.Api.System
 | 
			
		||||
            _security = security;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<object> Get(GetSupporterInfo request)
 | 
			
		||||
        {
 | 
			
		||||
            var result = await _security.GetSupporterInfo().ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            return ToOptimizedResult(result);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public object Post(PingSystem request)
 | 
			
		||||
        {
 | 
			
		||||
            return _appHost.Name;
 | 
			
		||||
 | 
			
		||||
@ -153,66 +153,6 @@ namespace MediaBrowser.Common.Implementations.Security
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task<SupporterInfo> GetSupporterInfo()
 | 
			
		||||
        {
 | 
			
		||||
            var key = SupporterKey;
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(key))
 | 
			
		||||
            {
 | 
			
		||||
                return new SupporterInfo();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var data = new Dictionary<string, string>
 | 
			
		||||
                {
 | 
			
		||||
                    { "key", key }, 
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            var url = MbAdmin.HttpsUrl + "/service/supporter/retrieve";
 | 
			
		||||
 | 
			
		||||
            using (var stream = await _httpClient.Post(url, data, CancellationToken.None).ConfigureAwait(false))
 | 
			
		||||
            {
 | 
			
		||||
                var response = _jsonSerializer.DeserializeFromStream<SuppporterInfoResponse>(stream);
 | 
			
		||||
 | 
			
		||||
                var info = new SupporterInfo
 | 
			
		||||
                {
 | 
			
		||||
                    Email = response.email,
 | 
			
		||||
                    PlanType = response.planType,
 | 
			
		||||
                    SupporterKey = response.supporterKey,
 | 
			
		||||
                    IsActiveSupporter = IsMBSupporter
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                if (!string.IsNullOrWhiteSpace(response.expDate))
 | 
			
		||||
                {
 | 
			
		||||
                    DateTime parsedDate;
 | 
			
		||||
                    if (DateTime.TryParse(response.expDate, out parsedDate))
 | 
			
		||||
                    {
 | 
			
		||||
                        info.ExpirationDate = parsedDate;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        _logger.Error("Failed to parse expDate: {0}", response.expDate);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (!string.IsNullOrWhiteSpace(response.regDate))
 | 
			
		||||
                {
 | 
			
		||||
                    DateTime parsedDate;
 | 
			
		||||
                    if (DateTime.TryParse(response.regDate, out parsedDate))
 | 
			
		||||
                    {
 | 
			
		||||
                        info.RegistrationDate = parsedDate;
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        _logger.Error("Failed to parse regDate: {0}", response.regDate);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                info.IsExpiredSupporter = info.ExpirationDate.HasValue && info.ExpirationDate < DateTime.UtcNow && !string.IsNullOrWhiteSpace(info.SupporterKey);
 | 
			
		||||
 | 
			
		||||
                return info;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Register an app store sale with our back-end.  It will validate the transaction with the store
 | 
			
		||||
        /// and then register the proper feature and then fill in the supporter key on success.
 | 
			
		||||
 | 
			
		||||
@ -185,7 +185,7 @@ namespace MediaBrowser.Common.Implementations.Updates
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Tuple<List<PackageInfo>, DateTime> _lastPackageListResult;
 | 
			
		||||
        private DateTime _lastPackageUpdateTime;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets all available packages.
 | 
			
		||||
@ -194,40 +194,89 @@ namespace MediaBrowser.Common.Implementations.Updates
 | 
			
		||||
        /// <returns>Task{List{PackageInfo}}.</returns>
 | 
			
		||||
        public async Task<IEnumerable<PackageInfo>> GetAvailablePackagesWithoutRegistrationInfo(CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            if (_lastPackageListResult != null)
 | 
			
		||||
            using (var stream = await GetCachedPackages(cancellationToken).ConfigureAwait(false))
 | 
			
		||||
            {
 | 
			
		||||
                TimeSpan cacheLength;
 | 
			
		||||
                var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(stream).ToList();
 | 
			
		||||
 | 
			
		||||
                if ((DateTime.UtcNow - _lastPackageUpdateTime) > GetCacheLength())
 | 
			
		||||
                {
 | 
			
		||||
                    UpdateCachedPackages(CancellationToken.None, false);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return packages;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private string PackageCachePath
 | 
			
		||||
        {
 | 
			
		||||
            get { return Path.Combine(_appPaths.CachePath, "serverpackages.json"); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<Stream> GetCachedPackages(CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                return _fileSystem.OpenRead(PackageCachePath);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            await UpdateCachedPackages(cancellationToken, true).ConfigureAwait(false);
 | 
			
		||||
            return _fileSystem.OpenRead(PackageCachePath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private readonly SemaphoreSlim _updateSemaphore = new SemaphoreSlim(1, 1);
 | 
			
		||||
        private async Task UpdateCachedPackages(CancellationToken cancellationToken, bool throwErrors)
 | 
			
		||||
        {
 | 
			
		||||
            await _updateSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if ((DateTime.UtcNow - _lastPackageUpdateTime) < GetCacheLength())
 | 
			
		||||
                {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var tempFile = await _httpClient.GetTempFile(new HttpRequestOptions
 | 
			
		||||
                {
 | 
			
		||||
                    Url = MbAdmin.HttpUrl + "service/MB3Packages.json",
 | 
			
		||||
                    CancellationToken = cancellationToken,
 | 
			
		||||
                    Progress = new Progress<Double>()
 | 
			
		||||
 | 
			
		||||
                }).ConfigureAwait(false);
 | 
			
		||||
 | 
			
		||||
                _fileSystem.CreateDirectory(Path.GetDirectoryName(PackageCachePath));
 | 
			
		||||
 | 
			
		||||
                _fileSystem.CopyFile(tempFile, PackageCachePath, true);
 | 
			
		||||
                _lastPackageUpdateTime = DateTime.UtcNow;
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                _logger.ErrorException("Error updating package cache", ex);
 | 
			
		||||
 | 
			
		||||
                if (throwErrors)
 | 
			
		||||
                {
 | 
			
		||||
                    throw;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                _updateSemaphore.Release();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private TimeSpan GetCacheLength()
 | 
			
		||||
        {
 | 
			
		||||
            switch (_config.CommonConfiguration.SystemUpdateLevel)
 | 
			
		||||
            {
 | 
			
		||||
                case PackageVersionClass.Beta:
 | 
			
		||||
                        cacheLength = TimeSpan.FromMinutes(30);
 | 
			
		||||
                        break;
 | 
			
		||||
                    return TimeSpan.FromMinutes(30);
 | 
			
		||||
                case PackageVersionClass.Dev:
 | 
			
		||||
                        cacheLength = TimeSpan.FromMinutes(3);
 | 
			
		||||
                        break;
 | 
			
		||||
                    return TimeSpan.FromMinutes(3);
 | 
			
		||||
                default:
 | 
			
		||||
                        cacheLength = TimeSpan.FromHours(24);
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if ((DateTime.UtcNow - _lastPackageListResult.Item2) < cacheLength)
 | 
			
		||||
                {
 | 
			
		||||
                    return _lastPackageListResult.Item1;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (var json = await _httpClient.Get(MbAdmin.HttpUrl + "service/MB3Packages.json", cancellationToken).ConfigureAwait(false))
 | 
			
		||||
            {
 | 
			
		||||
                cancellationToken.ThrowIfCancellationRequested();
 | 
			
		||||
 | 
			
		||||
                var packages = _jsonSerializer.DeserializeFromStream<List<PackageInfo>>(json).ToList();
 | 
			
		||||
 | 
			
		||||
                packages = FilterPackages(packages).ToList();
 | 
			
		||||
 | 
			
		||||
                _lastPackageListResult = new Tuple<List<PackageInfo>, DateTime>(packages, DateTime.UtcNow);
 | 
			
		||||
 | 
			
		||||
                return _lastPackageListResult.Item1;
 | 
			
		||||
                    return TimeSpan.FromHours(24);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,12 +41,6 @@ namespace MediaBrowser.Common.Security
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        Task LoadAllRegistrationInfo();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the supporter information.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>Task<SupporterInfo>.</returns>
 | 
			
		||||
        Task<SupporterInfo> GetSupporterInfo();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Register and app store sale with our back-end
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 | 
			
		||||
@ -608,9 +608,6 @@
 | 
			
		||||
    <Compile Include="..\MediaBrowser.Model\Entities\SortOrder.cs">
 | 
			
		||||
      <Link>Entities\SortOrder.cs</Link>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="..\MediaBrowser.Model\Entities\SupporterInfo.cs">
 | 
			
		||||
      <Link>Entities\SupporterInfo.cs</Link>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="..\MediaBrowser.Model\Entities\TrailerType.cs">
 | 
			
		||||
      <Link>Entities\TrailerType.cs</Link>
 | 
			
		||||
    </Compile>
 | 
			
		||||
 | 
			
		||||
@ -573,9 +573,6 @@
 | 
			
		||||
    <Compile Include="..\MediaBrowser.Model\Entities\SortOrder.cs">
 | 
			
		||||
      <Link>Entities\SortOrder.cs</Link>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="..\MediaBrowser.Model\Entities\SupporterInfo.cs">
 | 
			
		||||
      <Link>Entities\SupporterInfo.cs</Link>
 | 
			
		||||
    </Compile>
 | 
			
		||||
    <Compile Include="..\MediaBrowser.Model\Entities\TrailerType.cs">
 | 
			
		||||
      <Link>Entities\TrailerType.cs</Link>
 | 
			
		||||
    </Compile>
 | 
			
		||||
 | 
			
		||||
@ -1,15 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
 | 
			
		||||
namespace MediaBrowser.Model.Entities
 | 
			
		||||
{
 | 
			
		||||
    public class SupporterInfo
 | 
			
		||||
    {
 | 
			
		||||
        public string Email { get; set; }
 | 
			
		||||
        public string SupporterKey { get; set; }
 | 
			
		||||
        public DateTime? ExpirationDate { get; set; }
 | 
			
		||||
        public DateTime RegistrationDate { get; set; }
 | 
			
		||||
        public string PlanType { get; set; }
 | 
			
		||||
        public bool IsActiveSupporter { get; set; }
 | 
			
		||||
        public bool IsExpiredSupporter { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -144,7 +144,6 @@
 | 
			
		||||
    <Compile Include="Dto\MediaSourceType.cs" />
 | 
			
		||||
    <Compile Include="Configuration\DynamicDayOfWeek.cs" />
 | 
			
		||||
    <Compile Include="Entities\ExtraType.cs" />
 | 
			
		||||
    <Compile Include="Entities\SupporterInfo.cs" />
 | 
			
		||||
    <Compile Include="Entities\TrailerType.cs" />
 | 
			
		||||
    <Compile Include="Extensions\BoolHelper.cs" />
 | 
			
		||||
    <Compile Include="Extensions\FloatHelper.cs" />
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using CommonIO;
 | 
			
		||||
using MediaBrowser.Common.IO;
 | 
			
		||||
 | 
			
		||||
@ -40,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Connect
 | 
			
		||||
 | 
			
		||||
        public void Run()
 | 
			
		||||
        {
 | 
			
		||||
            LoadCachedAddress();
 | 
			
		||||
            Task.Run(() => LoadCachedAddress());
 | 
			
		||||
 | 
			
		||||
            _timer = new Timer(TimerCallback, null, TimeSpan.FromSeconds(5), TimeSpan.FromHours(3));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -1073,11 +1073,6 @@ namespace MediaBrowser.Server.Implementations.Connect
 | 
			
		||||
 | 
			
		||||
        public async Task<ConnectSupporterSummary> GetConnectSupporterSummary()
 | 
			
		||||
        {
 | 
			
		||||
            if (!_securityManager.IsMBSupporter)
 | 
			
		||||
            {
 | 
			
		||||
                return new ConnectSupporterSummary();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var url = GetConnectUrl("keyAssociation");
 | 
			
		||||
 | 
			
		||||
            var options = new HttpRequestOptions
 | 
			
		||||
@ -1106,11 +1101,6 @@ namespace MediaBrowser.Server.Implementations.Connect
 | 
			
		||||
 | 
			
		||||
        public async Task AddConnectSupporter(string id)
 | 
			
		||||
        {
 | 
			
		||||
            if (!_securityManager.IsMBSupporter)
 | 
			
		||||
            {
 | 
			
		||||
                throw new InvalidOperationException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var url = GetConnectUrl("keyAssociation");
 | 
			
		||||
 | 
			
		||||
            var options = new HttpRequestOptions
 | 
			
		||||
@ -1139,11 +1129,6 @@ namespace MediaBrowser.Server.Implementations.Connect
 | 
			
		||||
 | 
			
		||||
        public async Task RemoveConnectSupporter(string id)
 | 
			
		||||
        {
 | 
			
		||||
            if (!_securityManager.IsMBSupporter)
 | 
			
		||||
            {
 | 
			
		||||
                throw new InvalidOperationException();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var url = GetConnectUrl("keyAssociation");
 | 
			
		||||
 | 
			
		||||
            var options = new HttpRequestOptions
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Run()
 | 
			
		||||
        {
 | 
			
		||||
            _timer = new Timer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(24));
 | 
			
		||||
            _timer = new Timer(s => LoadAllRegistrations(), null, TimeSpan.FromMilliseconds(100), TimeSpan.FromHours(12));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task LoadAllRegistrations()
 | 
			
		||||
 | 
			
		||||
@ -1,148 +0,0 @@
 | 
			
		||||
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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Runs this instance.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void Run()
 | 
			
		||||
        {
 | 
			
		||||
            _timer = new Timer(OnTimerFired, null, TimeSpan.FromMilliseconds(500), _frequency);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Called when [timer fired].
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="state">The state.</param>
 | 
			
		||||
        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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Downloads the notifications.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="dataPath">The data path.</param>
 | 
			
		||||
        /// <param name="lastRunTime">The last run time.</param>
 | 
			
		||||
        /// <returns>Task.</returns>
 | 
			
		||||
        private async Task DownloadNotifications(string dataPath, DateTime lastRunTime)
 | 
			
		||||
        {
 | 
			
		||||
            using (var stream = await _httpClient.Get(new HttpRequestOptions
 | 
			
		||||
            {
 | 
			
		||||
                Url = Url
 | 
			
		||||
 | 
			
		||||
            }).ConfigureAwait(false))
 | 
			
		||||
            {
 | 
			
		||||
                var notifications = _json.DeserializeFromStream<RemoteNotification[]>(stream);
 | 
			
		||||
 | 
			
		||||
				_fileSystem.WriteAllText(dataPath, string.Empty);
 | 
			
		||||
 | 
			
		||||
                await CreateNotifications(notifications, lastRunTime).ConfigureAwait(false);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates the notifications.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="notifications">The notifications.</param>
 | 
			
		||||
        /// <param name="lastRunTime">The last run time.</param>
 | 
			
		||||
        /// <returns>Task.</returns>
 | 
			
		||||
        private async Task CreateNotifications(IEnumerable<RemoteNotification> 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; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -131,7 +131,6 @@
 | 
			
		||||
    <Compile Include="EntryPoints\LibraryChangedNotifier.cs" />
 | 
			
		||||
    <Compile Include="EntryPoints\LoadRegistrations.cs" />
 | 
			
		||||
    <Compile Include="EntryPoints\Notifications\Notifications.cs" />
 | 
			
		||||
    <Compile Include="EntryPoints\Notifications\RemoteNotifications.cs" />
 | 
			
		||||
    <Compile Include="EntryPoints\Notifications\WebSocketNotifier.cs" />
 | 
			
		||||
    <Compile Include="EntryPoints\RefreshUsersMetadata.cs" />
 | 
			
		||||
    <Compile Include="EntryPoints\UsageEntryPoint.cs" />
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user