示例#1
0
        /// <summary>
        /// Requests an upload url for each chunk of a file.
        /// </summary>
        /// <param name="transferId">The id of the global transfer.</param>
        /// <param name="fileData">A class containing data on the file to be uploaded.</param>
        /// <param name="partNumber">The partnumber of the chunk.</param>
        /// <returns></returns>
        internal async Task <FilePartUploadUrlResponse> RequestUploadUrl(string transferId,
                                                                         SingleFileTransferResponseData fileData,
                                                                         int partNumber)
        {
            using (var client = new HttpClient())
            {
                var request  = new FilePartUploadUrlRequestV2(ApiKey, Token, transferId, fileData.Id, partNumber);
                var response = await WaitForResponse <FilePartUploadUrlResponse>(client, request);

                response.PartNumber = partNumber;
                return(response);
            }
        }
示例#2
0
        public SingleFileUploadData(SingleFileTransferResponseData singleFileResponseData)
        {
            _responseData = singleFileResponseData ?? throw new ArgumentNullException(nameof(singleFileResponseData));

            var urls = new Dictionary <int, string>();

            for (var i = 1; i < _responseData.ChunkData.NumberOfParts; i++)
            {
                urls.Add(i, string.Empty);
            }

            UploadUrls = urls;
        }
示例#3
0
        /// <summary>
        /// Uploads a single file by requesting upload urls for each chunk, splitting the file according to the specified chunk size, uploading each chunk and signaling to the API that the file upload is complete.
        /// </summary>
        /// <param name="transferId">The id of the entire tranfser</param>
        /// <param name="singleFileTransferData">Data for the file that must be uploaded</param>
        /// <param name="progress">Used to report back progress</param>
        /// <param name="progressThusFar">Used to report back progress</param>
        /// <param name="maxAddableProgress">Used to report back progress</param>
        /// <returns></returns>
        internal async Task <UploadResultV2> UploadSingleFile(string transferId,
                                                              SingleFileTransferResponseData singleFileTransferData,
                                                              IProgress <ProgressReportV2> progress,
                                                              int progressThusFar,
                                                              int maxAddableProgress)
        {
            var fullPath = singleFileTransferData.FullPath;

            progress.Report(new ProgressReportV2($"Uploading '{Path.GetFileName(fullPath)}'...", (double)progressThusFar));

            // Split the files into the requested number of chuncks. The API has sent info on what chunksize to use when the transfer request was created.
            var currentStage = UploadResultV2.Stage.SplitFiles;
            //Logger.Debug("Splitting files...");
            await Task.Run(() => IOUtil.SplitFile(fullPath, singleFileTransferData.ChunkData.ChunkSize, ChunkDirectory));

            progress.Report(new ProgressReportV2("Files split", progressThusFar + maxAddableProgress / 5));
            //

            // Acquire the upload urls for each chunck of each file.
            currentStage = UploadResultV2.Stage.UploadUrl;
            //Logger.Debug("Requesting upload urls...");

            //Store the upload urls for each chunk.
            var uploadUrls = new List <FilePartUploadUrlResponse>();

            for (var i = 1; i <= singleFileTransferData.ChunkData.NumberOfParts; i++)
            {
                var partialUploadResponse = await RequestUploadUrl(transferId, singleFileTransferData, partNumber : i);

                if (!partialUploadResponse.Success.Value)
                {
                    return(new UploadResultV2(UploadResultV2.ResultCode.ApiError, currentStage, $"No upload url could be obtained for part {i}."));
                }
                uploadUrls.Add(partialUploadResponse);
            }

            progress.Report(new ProgressReportV2("Upload urls acquired", progressThusFar + maxAddableProgress / 4));
            //

            progressThusFar   += maxAddableProgress / 4;
            maxAddableProgress = maxAddableProgress * 3 / 4;

            // Upload each chunk.
            currentStage = UploadResultV2.Stage.Upload;
            //Logger.Debug("Uploading");
            foreach (var rp in uploadUrls)
            {
                var chunkPath      = Path.Combine(ChunkDirectory, rp.PartNumber.ToString());
                var uploadResponse = await UploadPart(rp.Url, chunkPath);

                if (!uploadResponse.Success.Value)
                {
                    return(new UploadResultV2(UploadResultV2.ResultCode.ApiError, currentStage, $"Part {rp.PartNumber} could not be uploaded."));
                }
                else
                {
                    var progressPercentage = maxAddableProgress * ((double)rp.PartNumber / (double)uploadUrls.Count);
                    progress.Report(new ProgressReportV2($"Part {rp.PartNumber} uploaded", progressThusFar + progressPercentage));
                }
            }
            //

            // Signal to the web API that we have finished.
            currentStage = UploadResultV2.Stage.Complete;
            var completeResponse = await CompleteSingleFileUpload(transferId, singleFileTransferData.Id, uploadUrls.Count);

            if (!completeResponse.Success.Value)
            {
                return(new UploadResultV2(UploadResultV2.ResultCode.ApiError, currentStage, completeResponse.Message));
            }
            else
            {
                progress.Report(new ProgressReportV2($"Upload of file '{Path.GetFileName(fullPath)}' completed", progressThusFar + maxAddableProgress));
                return(new UploadResultV2(UploadResultV2.ResultCode.Success, UploadResultV2.Stage.Complete, completeResponse.Message));
            }

            //
        }