/// <summary> /// Adds one or more files that will be uploaded as part of a new Photosynth collection. /// </summary> /// <param name="id">The Photosynth ID of the collection to add the files to.</param> /// <param name="addFilesRequest">Metadata about the files being uploaded.</param> /// <returns>Metadata used to upload the files themselves.</returns> public async Task <AddFilesResponse> AddFilesAsync(Guid id, AddFilesRequest addFilesRequest) { return(await this.MakeRequestAsync <AddFilesResponse>("/media/" + id + "/files", HttpMethod.Put, addFilesRequest)); }
/// <summary> /// Asynchronously uploads a synth packet to the Photosynth upload service for processing in the cloud. /// </summary> /// <param name="webApi">A WebApi object for handling HTTP communication with the Photosynth web service</param> /// <param name="fileStorage">An IFileStorage implementation for handling file I/O</param> /// <param name="synthPacketUpload">Metadata for the synth packet to be uploaded.</param> /// <param name="cancellationToken">A cancellation token.</param> /// <param name="parallelism">The maximum number of chunks that can be uploaded in parallel.</param> /// <returns>The task object representing the asynchronous operation</returns> public async Task UploadSynthPacketAsync( WebApi webApi, IFileStorage fileStorage, SynthPacketUpload synthPacketUpload, CancellationToken cancellationToken, int parallelism = 2) { if (this.IsUploading) { throw new InvalidOperationException("Only one upload at a time per Uploader instance is allowed."); } if (string.IsNullOrWhiteSpace(synthPacketUpload.Title)) { throw new ArgumentException("Must provide a Title for the SynthPacketUpload."); } try { this.IsUploading = true; this.Id = Guid.Empty; this.ProgressPercentage = 0; this.EstimatedTimeRemaining = string.Empty; this.FailedChunks.Clear(); // Create a new Photosynth collection this.Status = "Creating collection..."; var createCollectionRequest = new CreateMediaRequest() { UploadType = UploadType.SynthPacketFromRawImages }; var createCollectionResponse = await webApi.CreateMediaAsync(createCollectionRequest); this.ProgressPercentage = 1; this.Id = createCollectionResponse.Id; // Add images to the collection and get upload URLs for each file this.Status = "Adding images to collection..."; var addFilesRequest = new AddFilesRequest(); for (int i = 0; i < synthPacketUpload.PhotoPaths.Count; i++) { addFilesRequest.Files.Add(new AddFileRequest() { Id = i.ToString(), Extension = "jpg", Order = i.ToString("000"), ChunkCount = 1, }); } var addFilesResponse = await webApi.AddFilesAsync(this.Id, addFilesRequest); this.ProgressPercentage = 2; // Get info about all the files that need uploading List <ChunkInfo> chunks = addFilesRequest.Files.Join( addFilesResponse.Files, req => req.Id, resp => resp.ClientId, (req, resp) => { string photoPath = synthPacketUpload.PhotoPaths[Int32.Parse(resp.ClientId)]; FileChunk chunk = resp.Chunks.First(); return(new ChunkInfo(chunk.UploadUri, photoPath, fileStorage.GetFileSize(photoPath))); }).ToList(); // Commit the collection, no more files can be added this.Status = "Setting properties for the collection..."; var editMediaRequest = new EditMediaRequest() { Name = synthPacketUpload.Title, Description = synthPacketUpload.Description, ImageCount = synthPacketUpload.PhotoPaths.Count, PrivacyLevel = synthPacketUpload.PrivacyLevel, CapturedDate = synthPacketUpload.CapturedDate, Committed = true, SynthPacket = new SynthPacket() { License = synthPacketUpload.License, }, UploadHints = synthPacketUpload.Topology.ToString() // TODO geotag }; if (synthPacketUpload.Tags.Any()) { editMediaRequest.Tags = string.Join(",", synthPacketUpload.Tags); } await webApi.EditMediaAsync(this.Id, editMediaRequest); this.ProgressPercentage = 3; var failedChunks = await this.UploadChunksAsync(webApi, fileStorage, chunks, 3, cancellationToken, parallelism); foreach (var failedChunk in failedChunks) { this.FailedChunks.Add(failedChunk); } this.ProgressPercentage = 100; if (this.FailedChunks.Any()) { this.Status = string.Format(CultureInfo.CurrentUICulture, "{0} files failed to upload.", this.FailedChunks.Count); } else { this.Status = string.Format(CultureInfo.CurrentUICulture, "{0} files successfully uploaded.", chunks.Count); } } catch (Exception e) { this.Status = string.Format(CultureInfo.CurrentUICulture, "Error: {0}", e.Message); } finally { this.IsUploading = false; } }