コード例 #1
0
 public DownloaderObjectModel(
     ref HttpClient httpClient,
     string url,
     string destination,
     bool enqueue,
     EventHandler downloadCreatedEventHandler,
     EventHandler downloadVerifyingEventHandler,
     EventHandler downloadVerifiedEventHandler,
     EventHandler downloadStartedEventHandler,
     EventHandler downloadStoppedEventHandler,
     EventHandler downloadEnqueuedEventHandler,
     EventHandler downloadDequeuedEventHandler,
     EventHandler downloadFinishedEventHandler,
     PropertyChangedEventHandler propertyChangedEventHandler,
     IProgress <long> bytesReporter,
     ref RequestThrottler requestThrottler) : this(
         ref httpClient,
         url,
         destination,
         enqueue,
         totalBytesToDownload : null,
         httpStatusCode : null,
         downloadCreatedEventHandler,
         downloadVerifyingEventHandler,
         downloadVerifiedEventHandler,
         downloadStartedEventHandler,
         downloadStoppedEventHandler,
         downloadEnqueuedEventHandler,
         downloadDequeuedEventHandler,
         downloadFinishedEventHandler,
         propertyChangedEventHandler,
         bytesReporter,
         ref requestThrottler)
 {
 }
コード例 #2
0
        public void MultipleRequestWithSameApiKey()
        {
            //key TEST100 has rate Limit as 15
            apiKey = "TEST0000";

            int rateLimit = Config.GetRateLimitByAppId(apiKey);
            int successA = 0, successB = 0, successC = 0;

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    successA++;
                }

                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    successB++;
                }

                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    successC++;
                }
            }

            Assert.IsTrue((successA + successB + successC) == rateLimit);
        }
コード例 #3
0
        public async Task <HttpResponseMessage> FetchAllHotelAsync(DataSourceRequests request)
        {
            if (RequestThrottler.IsThrottled(request.ApiKey))
            {
                return(Request.CreateResponse((HttpStatusCode)429, "Too many requests."));
            }

            var result = await _hotelService.FetchAllHotels(request);

            return(Request.CreateResponse(HttpStatusCode.OK, result));
        }
コード例 #4
0
        public void Throttle_AsManyRequestsAsLimit_NoException()
        {
            var request  = Substitute.For <IHttpRequest>();
            var response = Substitute.For <IHttpResponse>();

            authenticate(request);
            setupRepository(request);
            setupConfiguration(request, 2, 30.Seconds());

            var subject = new RequestThrottler();

            Assert.That(() => subject.Throttle(request, response), Throws.Nothing);
            Assert.That(() => subject.Throttle(request, response), Throws.Nothing);
        }
コード例 #5
0
        public void WhenAppIdNotExistsInConfigAssignDefaultRate()
        {
            //Default rate limit is 10 in config.
            apiKey = "XXZZZZZ";
            int success = 0;

            int rateLimit = Config.GetRateLimitByAppId(apiKey);

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    success++;
                }
            }

            Assert.IsTrue(success == rateLimit);
        }
コード例 #6
0
        public void WhenRateLimitExceedsCheckIfKeyIsBlocked()
        {
            //key HD700 has default rate Limit 10
            apiKey = "HD700";
            bool isBlocked = false;

            for (int i = 1; i <= 11; i++)
            {
                if (RequestThrottler.IsThrottled(apiKey))
                {
                    if (RequestThrottler._cache.ContainsKey($"{apiKey}-BLOCKED"))
                    {
                        isBlocked = true;
                    }
                }
            }
            Assert.IsTrue(isBlocked);
        }
コード例 #7
0
        public void WhenNumberOfRequestIsEqualToRateLimit()
        {
            //key TEST100 has rate Limit as 15
            apiKey = "TEST102";

            int rateLimit = Config.GetRateLimitByAppId(apiKey);
            int success   = 0;

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    success++;
                }
            }

            Assert.IsTrue(rateLimit == success);
        }
コード例 #8
0
        public void WhenNumberOfRequestIsGreaterThanRateLimit()
        {
            //key TEST101 has rate Limit as 20
            apiKey = "TEST100";
            int success = 0, failed = 0;

            int rateLimit = Config.GetRateLimitByAppId(apiKey);

            for (int i = 1; i <= rateLimit; i++)
            {
                if (!RequestThrottler.IsThrottled(apiKey))
                {
                    success++;
                }
                else
                {
                    failed++;
                }
            }

            Assert.IsTrue(rateLimit - success == failed);
        }
コード例 #9
0
        public DownloaderViewModel(DisplayMessageDelegate displayMessage, ShowUrlsDelegate showUrls)
        {
            _client                           = new HttpClient();
            DownloadItemsList                 = new ObservableCollection <DownloaderObjectModel>();
            CategoriesList                    = new ObservableCollection <Category>();
            QueueProcessor                    = new QueueProcessor(Settings.Default.MaxParallelDownloads, QueueProcessor_PropertyChanged);
            _requestThrottler                 = new RequestThrottler(AppConstants.RequestThrottlerInterval);
            CollectionView                    = CollectionViewSource.GetDefaultView(DownloadItemsList);
            CollectionView.CurrentChanged    += CollectionView_CurrentChanged;
            _clipboardService                 = new ClipboardObserver();
            _semaphoreMeasuringSpeed          = new SemaphoreSlim(1);
            _semaphoreUpdatingList            = new SemaphoreSlim(1);
            _semaphoreRefreshingView          = new SemaphoreSlim(1);
            _ctsUpdatingList                  = null;
            _ctsRefreshView                   = null;
            _displayMessage                   = displayMessage;
            _lockDownloadItemsList            = DownloadItemsList;
            _lockBytesDownloaded              = this.BytesDownloaded;
            _lockBytesTransferredOverLifetime = Settings.Default.BytesTransferredOverLifetime;
            _showUrls                         = showUrls;
            this.Count                        = 0;
            this.DownloadingCount             = 0;
            this.ErroredCount                 = 0;
            this.FinishedCount                = 0;
            this.PausedCount                  = 0;
            this.QueuedCount                  = 0;
            this.ReadyCount                   = 0;
            this.VerifyingCount               = 0;
            this.BytesDownloaded              = 0;
            this.Status                       = "Ready";
            this.ProgressReporter             = new Progress <long>(value =>
            {
                Monitor.Enter(_lockBytesDownloaded);
                try
                {
                    this.BytesDownloaded += value;
                }
                finally
                {
                    Monitor.Exit(_lockBytesDownloaded);
                }
            });

            AddCommand                    = new RelayCommand <object>(Add);
            StartCommand                  = new RelayCommand <object>(Start);
            RemoveFromListCommand         = new RelayCommand <object>(RemoveFromList);
            CancelCommand                 = new RelayCommand <object>(Cancel);
            PauseCommand                  = new RelayCommand <object>(Pause);
            OpenCommand                   = new RelayCommand <object>(Open);
            OpenContainingFolderCommand   = new RelayCommand <object>(OpenContainingFolder);
            StartQueueCommand             = new RelayCommand <object>(StartQueue);
            StopQueueCommand              = new RelayCommand <object>(StopQueue);
            CloseAppCommand               = new RelayCommand <object>(CloseApp);
            CategoryChangedCommand        = new RelayCommand <object>(CategoryChanged);
            OptionsCommand                = new RelayCommand <object>(ShowOptions);
            EnqueueCommand                = new RelayCommand <object>(Enqueue);
            DequeueCommand                = new RelayCommand <object>(Dequeue);
            DeleteFileCommand             = new RelayCommand <object>(DeleteFile);
            RecheckCommand                = new RelayCommand <object>(Recheck);
            RedownloadCommand             = new RelayCommand <object>(Redownload);
            CopyLinkToClipboardCommand    = new RelayCommand <object>(CopyLinkToClipboard);
            ClearFinishedDownloadsCommand = new RelayCommand <object>(ClearFinishedDownloads);
            CancelBackgroundTaskCommand   = new RelayCommand <object>(
                CancelBackgroundTask, CancelBackgroundTask_CanExecute);
            CheckForUpdatesCommand = new RelayCommand <object>(CheckForUpdates);
            ShowHelpTopicsCommand  = new RelayCommand <object>(ShowHelpTopics);

            foreach (Category cat in (Category[])Enum.GetValues(typeof(Category)))
            {
                CategoriesList.Add(cat);
            }

            // Load last selected category
            if (string.IsNullOrEmpty(Settings.Default.LastSelectedCatagory))
            {
                SwitchCategory(Category.All);
            }
            else
            {
                SwitchCategory((Category)Enum.Parse(typeof(Category), Settings.Default.LastSelectedCatagory));
            }

            // Check for updates
            if (Settings.Default.AutoCheckForUpdates)
            {
                Task.Run(async() => await TriggerUpdateCheckAsync(true));
            }

            // Populate history
            Task.Run(async() =>
            {
                await _semaphoreUpdatingList.WaitAsync();

                _ctsUpdatingList = new CancellationTokenSource();
                var ct           = _ctsUpdatingList.Token;

                RaisePropertyChanged(nameof(this.IsBackgroundWorking));

                try
                {
                    if (Directory.Exists(AppPaths.LocalAppData))
                    {
                        this.Status = "Restoring data...";
                        RaisePropertyChanged(nameof(this.Status));
                    }
                    else
                    {
                        return;
                    }

                    SerializableDownloaderObjectModelList source;
                    var xmlReader = new XmlSerializer(typeof(SerializableDownloaderObjectModelList));

                    using (var streamReader = new StreamReader(AppPaths.DownloadsHistoryFile))
                    {
                        source = (SerializableDownloaderObjectModelList)xmlReader.Deserialize(streamReader);
                    }

                    var sourceObjects = source.Objects.ToArray();
                    var finalObjects  = new DownloaderObjectModel[sourceObjects.Count()];
                    var total         = sourceObjects.Count();

                    for (int i = 0; i < sourceObjects.Count(); i++)
                    {
                        if (ct.IsCancellationRequested)
                        {
                            break;
                        }
                        if (sourceObjects[i] == null)
                        {
                            continue;
                        }

                        int progress  = (int)((double)(i + 1) / total * 100);
                        this.Progress = progress;
                        this.Status   = "Restoring " + (i + 1) + " of " + total + ": " + sourceObjects[i].Url;
                        RaisePropertyChanged(nameof(this.Progress));
                        RaisePropertyChanged(nameof(this.Status));

                        var item = new DownloaderObjectModel(
                            ref _client,
                            sourceObjects[i].Url,
                            sourceObjects[i].Destination,
                            sourceObjects[i].IsQueued,
                            sourceObjects[i].TotalBytesToDownload,
                            sourceObjects[i].StatusCode,
                            Download_Created,
                            Download_Verifying,
                            Download_Verified,
                            Download_Started,
                            Download_Stopped,
                            Download_Enqueued,
                            Download_Dequeued,
                            Download_Finished,
                            Download_PropertyChanged,
                            ProgressReporter,
                            ref _requestThrottler);
                        item.SetCreationTime(sourceObjects[i].DateCreated);

                        finalObjects[i] = item;
                    }

                    this.Status = "Listing...";
                    RaisePropertyChanged(nameof(this.Status));

                    AddObjects(finalObjects);
                }
                catch
                {
                    return;
                }
                finally
                {
                    _ctsUpdatingList = null;

                    this.Progress = 0;
                    this.Status   = "Ready";
                    RaisePropertyChanged(nameof(this.Progress));
                    RaisePropertyChanged(nameof(this.Status));
                    RaisePropertyChanged(nameof(this.IsBackgroundWorking));

                    _semaphoreUpdatingList.Release();

                    RefreshCollection();
                }
            });
        }
コード例 #10
0
        public DownloaderObjectModel(
            ref HttpClient httpClient,
            string url,
            string destination,
            bool enqueue,
            long?totalBytesToDownload,
            HttpStatusCode?httpStatusCode,
            EventHandler downloadCreatedEventHandler,
            EventHandler downloadVerifyingEventHandler,
            EventHandler downloadVerifiedEventHandler,
            EventHandler downloadStartedEventHandler,
            EventHandler downloadStoppedEventHandler,
            EventHandler downloadEnqueuedEventHandler,
            EventHandler downloadDequeuedEventHandler,
            EventHandler downloadFinishedEventHandler,
            PropertyChangedEventHandler propertyChangedEventHandler,
            IProgress <long> bytesReporter,
            ref RequestThrottler requestThrottler)
        {
            _httpClient           = httpClient;
            _semaphoreDownloading = new SemaphoreSlim(1);
            _reportBytesProgress  = bytesReporter;
            _requestThrottler     = requestThrottler;
            TempDestination       = destination + AppConstants.DownloaderSplitedPartExtension;

            PropertyChanged   += propertyChangedEventHandler;
            DownloadCreated   += downloadCreatedEventHandler;
            DownloadVerifying += downloadVerifyingEventHandler;
            DownloadVerified  += downloadVerifiedEventHandler;
            DownloadStarted   += downloadStartedEventHandler;
            DownloadStopped   += downloadStoppedEventHandler;
            DownloadEnqueued  += downloadEnqueuedEventHandler;
            DownloadDequeued  += downloadDequeuedEventHandler;
            DownloadFinished  += downloadFinishedEventHandler;

            this.Name                       = Path.GetFileName(destination);
            this.Url                        = url;
            this.Destination                = destination;
            this.Status                     = DownloadStatus.Ready;
            this.Progress                   = 0;
            this.TotalBytesCompleted        = 0;
            this.TotalBytesToDownload       = null;
            this.BytesDownloadedThisSession = 0;
            this.SupportsResume             = false;
            this.Speed                      = null;
            this.DateCreated                = DateTime.Now;
            this.NumberOfActiveStreams      = null;
            this.StatusCode                 = null;
            this.TimeRemaining              = null;
            this.IsQueued                   = false;

            if (enqueue)
            {
                this.Enqueue();
            }

            _semaphoreDownloading.Wait();
            Task.Run(async() =>
            {
                if (totalBytesToDownload > 0)
                {
                    var restore = new RequestModel();
                    restore.TotalBytesToDownload = totalBytesToDownload;
                    restore.StatusCode           = httpStatusCode;
                    restore.Url = url;
                    await VerifyDownloadAsync(url, restore);
                }
                else
                {
                    await VerifyDownloadAsync(url);
                }
                _semaphoreDownloading.Release();
            });

            RaiseEvent(DownloadCreated);
        }