Пример #1
0
 public void RegisterStopCallback(Action <object> callback, object state)
 {
     StoppingCount++;
     StoppingAction?.Invoke(callback, state);
 }
Пример #2
0
 public void Add(IUserIdentifier userIdentifier, StoppingAction stoppingAction)
 {
     _map.Add(userIdentifier.GetKey(), stoppingAction);
 }
Пример #3
0
        public async IAsyncEnumerable <DropboxFileInfo> DownloadAsync(
            IUserIdentifier userIdentifier,
            string apiToken,
            StoppingAction stoppingAction,
            [EnumeratorCancellation] CancellationToken cancellationToken)
        {
            CreateClient(apiToken);

            var account = await WrapApiCallAsync(_dropboxClient.Users.GetCurrentAccountAsync);

            _state = _stateService.GetState(account.AccountId);
            if (_state != null)
            {
                _lastProcessedFileIndex = _state.LastProcessedFileIndex;
            }
            else
            {
                _state = new DropboxDownloadState {
                    Started = DateTimeOffset.Now, AccountId = account.AccountId
                }
            };

            bool firstIteration = true;
            var  filesMetadata  = new List <Metadata>();

            var listFolderResult = await WrapApiCallAsync(() => _dropboxClient.Files.ListFolderAsync(CameraUploads, limit: Limit));

            while (listFolderResult.HasMore || firstIteration)
            {
                if (!firstIteration)
                {
                    listFolderResult = await WrapApiCallAsync(() =>
                                                              _dropboxClient.Files.ListFolderContinueAsync(listFolderResult.Cursor));
                }

                filesMetadata.AddRange(listFolderResult.Entries.Where(a => a is FileMetadata));

                firstIteration = false;
            }

            _state.TotalFiles = filesMetadata.Count;

            var index = _lastProcessedFileIndex > -1 ? _lastProcessedFileIndex : 0;

            for (int i = index; i < filesMetadata.Count; i++)
            {
                if (cancellationToken.IsCancellationRequested || stoppingAction.IsStopRequested)
                {
                    _logger.LogInformation("Cancellation requested.");
                    yield break;
                }

                var fileMetadata = filesMetadata[i];

                var dropboxFile = await DownloadFileAsync(fileMetadata, account);

                if (dropboxFile == null)
                {
                    yield break;
                }

                _state.LastProcessedFileIndex++;
                _state.LastProcessedFileId = dropboxFile.FileId;

                _progressReporter.Report(userIdentifier, _state.LastProcessedFileIndex, _state.TotalFiles);

                yield return(dropboxFile);
            }
        }
        public async IAsyncEnumerable <YandexDiskFileInfo> DownloadFilesAsync(
            IUserIdentifier userIdentifier,
            string accessToken,
            [EnumeratorCancellation] CancellationToken cancellationToken,
            StoppingAction stoppingAction)
        {
            var apiClient = new ApiClient(accessToken, Client);

            _data = _yandexDiskDownloadStateService.GetData(userIdentifier.UserId);
            if (_data == null)
            {
                _data = new YandexDiskData {
                    UserId = userIdentifier.UserId, YandexDiskAccessToken = accessToken
                };
            }
            else
            {
                _currentOffset = _data.CurrentIndex;
            }

            var disk = await WrapApiCallAsync(() => apiClient.GetDiskAsync(cancellationToken));

            bool firstIteration = true;

            while (_currentOffset <= _totalFiles || firstIteration)
            {
                var resource =
                    await WrapApiCallAsync(() =>
                                           apiClient.GetResourceAsync(disk.SystemFolders.Photostream, cancellationToken, _currentOffset, Limit));

                _totalFiles = resource.Embedded.Total;

                var items = resource.Embedded.Items;
                if (items != null && items.Length > 0)
                {
                    foreach (var item in items)
                    {
                        if (cancellationToken.IsCancellationRequested || stoppingAction.IsStopRequested)
                        {
                            _logger.LogInformation("Cancellation requested.");
                            yield break;
                        }

                        if (item.MediaType == "video")
                        {
                            _currentOffset++;
                            continue;
                        }

                        var entity = await DownloadAsync(item, disk);

                        if (entity == null)
                        {
                            yield break;
                        }

                        _currentOffset++;

                        _progressReporter.Report(userIdentifier, _currentOffset, _totalFiles);

                        yield return(entity);
                    }
                }

                firstIteration = false;
            }
        }
        public override async Task HandleAsync(EventBase @event, CancellationToken cancellationToken)
        {
            if (@event is StartProcessingEvent startProcessingCommand)
            {
                using var scope = _serviceScopeFactory.CreateScope();

                var userIdentifier = startProcessingCommand.UserIdentifier;

                var stoppingAction = new StoppingAction();
                _downloadManager.Add(userIdentifier, stoppingAction);

                var startedNotification = CreateNotification(userIdentifier, ProcessingStatus.Running);
                _messageSender.Send(startedNotification, Constants.PhotoMapApi);

                if (userIdentifier is YandexDiskUserIdentifier)
                {
                    var yandexDiskDownloadService = scope.ServiceProvider.GetService <IYandexDiskDownloadService>();

                    try
                    {
                        await foreach (var file in yandexDiskDownloadService.DownloadFilesAsync(userIdentifier,
                                                                                                startProcessingCommand.Token, cancellationToken, stoppingAction))
                        {
                            var processedDownloadedFile = await _imageProcessingService.ProcessImageAsync(file);

                            var imageProcessedEvent = CreateResultsCommand(startProcessingCommand.UserIdentifier, processedDownloadedFile);
                            _messageSender.Send(imageProcessedEvent, Constants.PhotoMapApi);
                        }
                    }
                    catch (Exception e)
                    {
                        _logger.LogError(e.Message);

                        var stoppedNotification =
                            CreateNotification(userIdentifier, ProcessingStatus.NotRunning, true, e.Message);
                        _messageSender.Send(stoppedNotification, Constants.PhotoMapApi);
                    }
                    finally
                    {
                        _downloadManager.Remove(userIdentifier);

                        var finishedNotification = CreateNotification(userIdentifier, ProcessingStatus.NotRunning);
                        _messageSender.Send(finishedNotification, Constants.PhotoMapApi);

                        _logger.LogInformation("Processing finished");
                    }
                }
                else if (userIdentifier is DropboxUserIdentifier)
                {
                    var dropboxDownloadService = scope.ServiceProvider.GetService <IDropboxDownloadService>();

                    try
                    {
                        await foreach (var file in dropboxDownloadService.DownloadAsync(userIdentifier,
                                                                                        startProcessingCommand.Token, stoppingAction, cancellationToken))
                        {
                            var processedDownloadedFile = await _imageProcessingService.ProcessImageAsync(file);

                            var imageProcessedEvent = CreateResultsCommand(startProcessingCommand.UserIdentifier, processedDownloadedFile);
                            _messageSender.Send(imageProcessedEvent, Constants.PhotoMapApi);
                        }
                    }
                    catch (Exception e)
                    {
                        _logger.LogError(e.Message);

                        var stoppedNotification =
                            CreateNotification(userIdentifier, ProcessingStatus.NotRunning, true, e.Message);
                        _messageSender.Send(stoppedNotification, Constants.PhotoMapApi);
                    }
                    finally
                    {
                        _downloadManager.Remove(userIdentifier);

                        var finishedNotification = CreateNotification(userIdentifier, ProcessingStatus.NotRunning);
                        _messageSender.Send(finishedNotification, Constants.PhotoMapApi);

                        _logger.LogInformation("Processing finished.");
                    }
                }
            }
        }