/// <summary> /// Creates a new transfer. The files to upload must be specified up front. /// </summary> /// <param name="fileRequest">A class containing data on the global transfer as well as on the separate files to upload.</param> /// <returns></returns> /// <remarks>The full paths to the files are added to the API's response in order to keep track of them. /// Note: currently the implementation will fail when two files have the same name, but are located in different directories!</remarks> internal async Task <TransferRequestResponseV2> CreateTransfer(FileUploadRequestContent fileRequest) { using (var client = new HttpClient()) { var request = new CreateTransferRequestV2(ApiKey, Token, fileRequest); var createTransferResponse = await WaitForResponse <TransferRequestResponseV2>(client, request); foreach (var file in createTransferResponse.Files) { file.FullPath = fileRequest.Files.Single(f => f.Name == file.Name).FullPath; } return(createTransferResponse); } }
/// <summary> /// The main entry for the component. Will handle all stages of the upload. /// </summary> /// <param name="fullPaths">A collection of paths for the transfer</param> /// <param name="requestName">The (arbitrary) name for the transfer</param> /// <param name="user">The name of the user that will obtain the token. Is mainly iseful for creating Boards.</param> /// <param name="progress">An optional parameter to report back progress to the calling code.</param> /// <returns></returns> public async Task <UploadResultV2> UploadFiles(IEnumerable <string> fullPaths, string requestName, string user, IProgress <ProgressReportV2> progress = null) { //Validation if (fullPaths == null || fullPaths.Count() == 0) { throw new ArgumentNullException(nameof(fullPaths)); } foreach (var path in fullPaths) { if (!File.Exists(path)) { throw new FileNotFoundException(path); } } if (string.IsNullOrEmpty(user)) { throw new ArgumentNullException(nameof(user)); } // UploadResultV2.Stage currentStage = UploadResultV2.Stage.NotSet; try { // If no progress was passed, create an empty one. In this way we do not have to check for null each time we want to report progress. if (progress == null) { progress = new Progress <ProgressReportV2>(); } // Use existing token or request a new one. currentStage = UploadResultV2.Stage.Token; if (string.IsNullOrEmpty(Token)) { //Logger.Debug("No token. Obtaining new one..."); var obtainTokenResult = await GetToken(user); if (!obtainTokenResult.Success.Value) { return(new UploadResultV2(UploadResultV2.ResultCode.ApiError, currentStage, "Token could not be obtained.")); } else { progress.Report(new ProgressReportV2("New token obtained", 5)); } } // // Create a new transfer request. currentStage = UploadResultV2.Stage.TransferRequest; //Logger.Debug("Creating transfer..."); //Calculate the filesizes in order to report correct progress var fileInfos = new List <FileInfo>(); //Create the data for the files that must be uploaded. var fileRequests = new List <FileRequestContent>(); foreach (var file in fullPaths) { var info = new FileInfo(file); fileInfos.Add(info); var fileRequest = new FileRequestContent(info.Name, (int)info.Length, info.FullName); fileRequests.Add(fileRequest); } var content = new FileUploadRequestContent(requestName, fileRequests.ToArray()); var createTransferResponse = await CreateTransfer(content); if (!createTransferResponse.Success.Value) { return(new UploadResultV2(UploadResultV2.ResultCode.ApiError, currentStage, "No transfer could be created.")); } else { progress.Report(new ProgressReportV2("Transfer created", 10)); } // var totalFileSize = fileInfos.Sum(info => info.Length); // Add the files to the transfer currentStage = UploadResultV2.Stage.AddFiles; var currentProgess = 10; foreach (var file in createTransferResponse.Files) { var addableProgressForThisFile = 90 * ((double)file.ChunkData.ChunkSize * file.ChunkData.NumberOfParts / (double)totalFileSize); var result = await UploadSingleFile(createTransferResponse.Id, file, progress, progressThusFar : currentProgess, maxAddableProgress : (int)addableProgressForThisFile); if (result.Result != UploadResultV2.ResultCode.Success) { return(result); } currentProgess += (int)addableProgressForThisFile; } var completionResponse = await CompleteTransfer(createTransferResponse.Id); return(new UploadResultV2(UploadResultV2.ResultCode.Success, UploadResultV2.Stage.Complete, "All files uploaded", completionResponse.DownloadUrl)); } catch (TaskCanceledException ex) { return(new UploadResultV2(UploadResultV2.ResultCode.NoConnection, currentStage, ex.Message)); } catch (Exception ex) { return(new UploadResultV2(UploadResultV2.ResultCode.UnknownError, currentStage, ex.Message)); } }