From acf73dafce3b32be5ac52e6e399c86cb86aacdf8 Mon Sep 17 00:00:00 2001 From: JayH Date: Sun, 23 Feb 2020 14:16:50 -0500 Subject: [PATCH 1/3] Fixed issue with object paging so see all objects in bucket (the issue is still probably in the bucket paging). Added filter field to return a filtered list of objects in the bucket when it's refreshed. Added a display manifest but to show an objects manifest which contains the status and potentially the reason the transformation failed. --- bucket.manager/DisplayText.Designer.cs | 77 +++++ bucket.manager/DisplayText.cs | 31 ++ bucket.manager/DisplayText.resx | 120 +++++++ bucket.manager/Form1.Designer.cs | 88 +++-- bucket.manager/Form1.cs | 62 +++- bucket.manager/Form1.cs.bak | 455 +++++++++++++++++++++++++ bucket.manager/Utils/CustomProgress.cs | 2 +- bucket.manager/bucket.manager.csproj | 9 + 8 files changed, 813 insertions(+), 31 deletions(-) create mode 100644 bucket.manager/DisplayText.Designer.cs create mode 100644 bucket.manager/DisplayText.cs create mode 100644 bucket.manager/DisplayText.resx create mode 100644 bucket.manager/Form1.cs.bak diff --git a/bucket.manager/DisplayText.Designer.cs b/bucket.manager/DisplayText.Designer.cs new file mode 100644 index 0000000..3740fdf --- /dev/null +++ b/bucket.manager/DisplayText.Designer.cs @@ -0,0 +1,77 @@ +namespace bucket.manager +{ + partial class DisplayText + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tbText = new System.Windows.Forms.TextBox(); + this.btnClose = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // tbText + // + this.tbText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbText.Location = new System.Drawing.Point(2, 3); + this.tbText.Multiline = true; + this.tbText.Name = "tbText"; + this.tbText.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.tbText.Size = new System.Drawing.Size(752, 375); + this.tbText.TabIndex = 0; + // + // btnClose + // + this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnClose.Location = new System.Drawing.Point(12, 386); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(75, 23); + this.btnClose.TabIndex = 1; + this.btnClose.Text = "Close"; + this.btnClose.UseVisualStyleBackColor = true; + this.btnClose.Click += new System.EventHandler(this.btnClose_Click); + // + // DisplayText + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(757, 421); + this.Controls.Add(this.btnClose); + this.Controls.Add(this.tbText); + this.Name = "DisplayText"; + this.Text = "DisplayText"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox tbText; + private System.Windows.Forms.Button btnClose; + } +} \ No newline at end of file diff --git a/bucket.manager/DisplayText.cs b/bucket.manager/DisplayText.cs new file mode 100644 index 0000000..92923e1 --- /dev/null +++ b/bucket.manager/DisplayText.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace bucket.manager +{ + public partial class DisplayText : Form + { + public DisplayText() + { + InitializeComponent(); + } + + public DisplayText(string theText) + { + InitializeComponent(); + this.tbText.Text = theText; + } + + private void btnClose_Click(object sender, EventArgs e) + { + this.Close(); + } + } +} diff --git a/bucket.manager/DisplayText.resx b/bucket.manager/DisplayText.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/bucket.manager/DisplayText.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/bucket.manager/Form1.Designer.cs b/bucket.manager/Form1.Designer.cs index 2e50816..bb1e14e 100644 --- a/bucket.manager/Form1.Designer.cs +++ b/bucket.manager/Form1.Designer.cs @@ -67,7 +67,10 @@ private void InitializeComponent() this.btnShowDevTools = new System.Windows.Forms.Button(); this.btnDownloadSVF = new System.Windows.Forms.Button(); this.btnJavaScript = new System.Windows.Forms.Button(); + this.tbFilter = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); this.progressBar = new bucket.manager.Utils.CustomProgressBar(); + this.btnManifest = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // @@ -75,9 +78,9 @@ private void InitializeComponent() // this.treeBuckets.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); - this.treeBuckets.Location = new System.Drawing.Point(12, 182); + this.treeBuckets.Location = new System.Drawing.Point(12, 208); this.treeBuckets.Name = "treeBuckets"; - this.treeBuckets.Size = new System.Drawing.Size(225, 419); + this.treeBuckets.Size = new System.Drawing.Size(225, 393); this.treeBuckets.TabIndex = 0; this.treeBuckets.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeBuckets_AfterSelect); // @@ -104,7 +107,7 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.label1); this.groupBox1.Location = new System.Drawing.Point(13, 13); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(675, 76); + this.groupBox1.Size = new System.Drawing.Size(1092, 76); this.groupBox1.TabIndex = 2; this.groupBox1.TabStop = false; this.groupBox1.Text = "Forge Credentials"; @@ -112,7 +115,7 @@ private void InitializeComponent() // txtTimeout // this.txtTimeout.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtTimeout.Location = new System.Drawing.Point(583, 46); + this.txtTimeout.Location = new System.Drawing.Point(1000, 46); this.txtTimeout.Name = "txtTimeout"; this.txtTimeout.ReadOnly = true; this.txtTimeout.Size = new System.Drawing.Size(86, 20); @@ -126,7 +129,7 @@ private void InitializeComponent() this.txtAccessToken.Location = new System.Drawing.Point(100, 46); this.txtAccessToken.Name = "txtAccessToken"; this.txtAccessToken.ReadOnly = true; - this.txtAccessToken.Size = new System.Drawing.Size(477, 20); + this.txtAccessToken.Size = new System.Drawing.Size(894, 20); this.txtAccessToken.TabIndex = 9; // // label4 @@ -141,7 +144,7 @@ private void InitializeComponent() // btnAuthenticate // this.btnAuthenticate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnAuthenticate.Location = new System.Drawing.Point(583, 18); + this.btnAuthenticate.Location = new System.Drawing.Point(1000, 18); this.btnAuthenticate.Name = "btnAuthenticate"; this.btnAuthenticate.Size = new System.Drawing.Size(86, 23); this.btnAuthenticate.TabIndex = 5; @@ -152,7 +155,7 @@ private void InitializeComponent() // txtClientSecret // this.txtClientSecret.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtClientSecret.Location = new System.Drawing.Point(384, 20); + this.txtClientSecret.Location = new System.Drawing.Point(801, 20); this.txtClientSecret.Name = "txtClientSecret"; this.txtClientSecret.PasswordChar = '*'; this.txtClientSecret.Size = new System.Drawing.Size(193, 20); @@ -162,7 +165,7 @@ private void InitializeComponent() // this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(337, 24); + this.label2.Location = new System.Drawing.Point(754, 24); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(41, 13); this.label2.TabIndex = 3; @@ -174,14 +177,14 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.txtClientId.Location = new System.Drawing.Point(35, 20); this.txtClientId.Name = "txtClientId"; - this.txtClientId.Size = new System.Drawing.Size(296, 20); + this.txtClientId.Size = new System.Drawing.Size(713, 20); this.txtClientId.TabIndex = 2; // // btnRefreshToken // - this.btnRefreshToken.Location = new System.Drawing.Point(13, 95); + this.btnRefreshToken.Location = new System.Drawing.Point(12, 95); this.btnRefreshToken.Name = "btnRefreshToken"; - this.btnRefreshToken.Size = new System.Drawing.Size(121, 23); + this.btnRefreshToken.Size = new System.Drawing.Size(108, 23); this.btnRefreshToken.TabIndex = 3; this.btnRefreshToken.Text = "Refresh buckets"; this.btnRefreshToken.UseVisualStyleBackColor = true; @@ -189,9 +192,9 @@ private void InitializeComponent() // // btnCreateBucket // - this.btnCreateBucket.Location = new System.Drawing.Point(140, 95); + this.btnCreateBucket.Location = new System.Drawing.Point(129, 95); this.btnCreateBucket.Name = "btnCreateBucket"; - this.btnCreateBucket.Size = new System.Drawing.Size(97, 23); + this.btnCreateBucket.Size = new System.Drawing.Size(108, 23); this.btnCreateBucket.TabIndex = 4; this.btnCreateBucket.Text = "Create Bucket"; this.btnCreateBucket.UseVisualStyleBackColor = true; @@ -199,9 +202,9 @@ private void InitializeComponent() // // btnUpload // - this.btnUpload.Location = new System.Drawing.Point(13, 153); + this.btnUpload.Location = new System.Drawing.Point(12, 150); this.btnUpload.Name = "btnUpload"; - this.btnUpload.Size = new System.Drawing.Size(93, 23); + this.btnUpload.Size = new System.Drawing.Size(108, 23); this.btnUpload.TabIndex = 5; this.btnUpload.Text = "Upload File"; this.btnUpload.UseVisualStyleBackColor = true; @@ -209,11 +212,11 @@ private void InitializeComponent() // // btnTranslate // - this.btnTranslate.Location = new System.Drawing.Point(113, 153); + this.btnTranslate.Location = new System.Drawing.Point(12, 179); this.btnTranslate.Name = "btnTranslate"; - this.btnTranslate.Size = new System.Drawing.Size(124, 23); + this.btnTranslate.Size = new System.Drawing.Size(108, 23); this.btnTranslate.TabIndex = 6; - this.btnTranslate.Text = "Translate file"; + this.btnTranslate.Text = "Translate File"; this.btnTranslate.UseVisualStyleBackColor = true; this.btnTranslate.Click += new System.EventHandler(this.btnTranslate_Click); // @@ -225,9 +228,9 @@ private void InitializeComponent() // // btnDeleteObject // - this.btnDeleteObject.Location = new System.Drawing.Point(13, 124); + this.btnDeleteObject.Location = new System.Drawing.Point(129, 150); this.btnDeleteObject.Name = "btnDeleteObject"; - this.btnDeleteObject.Size = new System.Drawing.Size(103, 23); + this.btnDeleteObject.Size = new System.Drawing.Size(108, 23); this.btnDeleteObject.TabIndex = 8; this.btnDeleteObject.Text = "Delete Object"; this.btnDeleteObject.UseVisualStyleBackColor = true; @@ -241,13 +244,13 @@ private void InitializeComponent() this.panel1.Location = new System.Drawing.Point(242, 95); this.panel1.Margin = new System.Windows.Forms.Padding(2); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(446, 477); + this.panel1.Size = new System.Drawing.Size(863, 477); this.panel1.TabIndex = 9; // // btnShowDevTools // this.btnShowDevTools.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnShowDevTools.Location = new System.Drawing.Point(613, 577); + this.btnShowDevTools.Location = new System.Drawing.Point(1030, 577); this.btnShowDevTools.Name = "btnShowDevTools"; this.btnShowDevTools.Size = new System.Drawing.Size(75, 23); this.btnShowDevTools.TabIndex = 10; @@ -258,7 +261,7 @@ private void InitializeComponent() // btnDownloadSVF // this.btnDownloadSVF.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnDownloadSVF.Location = new System.Drawing.Point(492, 577); + this.btnDownloadSVF.Location = new System.Drawing.Point(909, 577); this.btnDownloadSVF.Name = "btnDownloadSVF"; this.btnDownloadSVF.Size = new System.Drawing.Size(115, 23); this.btnDownloadSVF.TabIndex = 11; @@ -269,7 +272,7 @@ private void InitializeComponent() // btnJavaScript // this.btnJavaScript.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnJavaScript.Location = new System.Drawing.Point(411, 577); + this.btnJavaScript.Location = new System.Drawing.Point(828, 577); this.btnJavaScript.Name = "btnJavaScript"; this.btnJavaScript.Size = new System.Drawing.Size(75, 23); this.btnJavaScript.TabIndex = 12; @@ -277,6 +280,22 @@ private void InitializeComponent() this.btnJavaScript.UseVisualStyleBackColor = true; this.btnJavaScript.Click += new System.EventHandler(this.btnJavaScript_Click); // + // tbFilter + // + this.tbFilter.Location = new System.Drawing.Point(48, 124); + this.tbFilter.Name = "tbFilter"; + this.tbFilter.Size = new System.Drawing.Size(189, 20); + this.tbFilter.TabIndex = 13; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 128); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(29, 13); + this.label3.TabIndex = 14; + this.label3.Text = "Filter"; + // // progressBar // this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) @@ -285,15 +304,28 @@ private void InitializeComponent() this.progressBar.DisplayStyle = bucket.manager.Utils.ProgressBarDisplayText.Percentage; this.progressBar.Location = new System.Drawing.Point(12, 607); this.progressBar.Name = "progressBar"; - this.progressBar.Size = new System.Drawing.Size(676, 23); + this.progressBar.Size = new System.Drawing.Size(1093, 23); this.progressBar.TabIndex = 7; this.progressBar.Visible = false; // + // btnManifest + // + this.btnManifest.Location = new System.Drawing.Point(129, 179); + this.btnManifest.Name = "btnManifest"; + this.btnManifest.Size = new System.Drawing.Size(108, 23); + this.btnManifest.TabIndex = 15; + this.btnManifest.Text = "Show Manifest"; + this.btnManifest.UseVisualStyleBackColor = true; + this.btnManifest.Click += new System.EventHandler(this.btnManifest_Click); + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(700, 642); + this.ClientSize = new System.Drawing.Size(1117, 642); + this.Controls.Add(this.btnManifest); + this.Controls.Add(this.label3); + this.Controls.Add(this.tbFilter); this.Controls.Add(this.btnJavaScript); this.Controls.Add(this.btnDownloadSVF); this.Controls.Add(this.btnShowDevTools); @@ -314,6 +346,7 @@ private void InitializeComponent() this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.ResumeLayout(false); + this.PerformLayout(); } @@ -340,6 +373,9 @@ private void InitializeComponent() private System.Windows.Forms.Button btnShowDevTools; private System.Windows.Forms.Button btnDownloadSVF; private System.Windows.Forms.Button btnJavaScript; + private System.Windows.Forms.TextBox tbFilter; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button btnManifest; } } diff --git a/bucket.manager/Form1.cs b/bucket.manager/Form1.cs index e0364b5..c7b92dd 100644 --- a/bucket.manager/Form1.cs +++ b/bucket.manager/Form1.cs @@ -131,23 +131,51 @@ private async void btnRefreshToken_Click(object sender, EventArgs e) foreach (TreeNode n in treeBuckets.Nodes) if (n != null) // async? await ShowBucketObjects(n); + + treeBuckets.Sort(); } private async Task ShowBucketObjects(TreeNode nodeBucket) { + string filter = tbFilter.Text; + if (filter == "") filter = null; + nodeBucket.Nodes.Clear(); + // control GetBucket pagination + string lastNode = null; + int itemCount = 0; + ObjectsApi objects = new ObjectsApi(); objects.Configuration.AccessToken = AccessToken; // show objects on the given TreeNode - var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag); + do + { + var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag, 100, filter, lastNode); //"24288A-1000" + itemCount += objectsList.items.Count; + if (itemCount == 0) break; + if (((DynamicJsonResponse)objectsList).Dictionary.ContainsKey("next") && objectsList.next != null) + { + lastNode = ((string)objectsList.next); + int start = lastNode.IndexOf("startAt=") + 8; + int end = lastNode.IndexOf("&limit="); + lastNode = Uri.UnescapeDataString(lastNode.Substring(start, end - start)); + } + else + { + lastNode = null; + } + foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) { TreeNode nodeObject = new TreeNode(objInfo.Value.objectKey); nodeObject.Tag = ((string)objInfo.Value.objectId).Base64Encode(); nodeBucket.Nodes.Add(nodeObject); + } + if (lastNode == null) break; + } while ((itemCount % 100) == 0); } private const int UPLOAD_CHUNK_SIZE = 2; // Mb @@ -177,8 +205,8 @@ private async void btnUpload_Click(object sender, EventArgs e) // show progress bar for upload progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; progressBar.Show(); - progressBar.Value = 0; progressBar.Minimum = 0; + progressBar.Value = 0; progressBar.CustomText = "Preparing to upload file..."; // decide if upload direct or resumable (by chunks) @@ -224,8 +252,8 @@ private async void btnUpload_Click(object sender, EventArgs e) { using (StreamReader streamReader = new StreamReader(filePath)) { - progressBar.Value = 50; // random... progressBar.Maximum = 100; + progressBar.Value = 50; // random... dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream"); @@ -253,6 +281,32 @@ private void btnTranslate_Click(object sender, EventArgs e) menuTranslate.Show(btnTranslate, new Point(0, btnTranslate.Height)); } + private void btnManifest_Click(object sender, EventArgs e) + { + // check level 1 of objects + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string urn = (string)treeBuckets.SelectedNode.Tag; + + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = AccessToken; + try + { + string aManifest = derivative.GetManifest(urn).ToString(); + + using (var displayText = new DisplayText(aManifest)) + { + displayText.ShowDialog(); + } + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private async void onClickTranslate(object sender, EventArgs e) { // for now, just one translation at a time @@ -285,9 +339,9 @@ private async void onClickTranslate(object sender, EventArgs e) // start progress bar for translation progressBar.Show(); - progressBar.Value = 0; progressBar.Minimum = 0; progressBar.Maximum = 100; + progressBar.Value = 0; progressBar.CustomText = "Starting translation job..."; // start translation job diff --git a/bucket.manager/Form1.cs.bak b/bucket.manager/Form1.cs.bak new file mode 100644 index 0000000..d4c338a --- /dev/null +++ b/bucket.manager/Form1.cs.bak @@ -0,0 +1,455 @@ +///////////////////////////////////////////////////////////////////// +// Copyright (c) Autodesk, Inc. All rights reserved +// Written by Forge Partner Development +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +///////////////////////////////////////////////////////////////////// + +using Autodesk.Forge; +using Autodesk.Forge.Model; +using bucket.manager.Utils; +using CefSharp; +using CefSharp.WinForms; +using RestSharp; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace bucket.manager +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + InitBrowser(); + } + + public ChromiumWebBrowser browser; + + public void InitBrowser() + { + Cef.Initialize(new CefSettings()); + browser = new ChromiumWebBrowser("file:///HTML/Viewer.html"); // CefSharp needs a initial page... + + browser.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + browser.MinimumSize = new System.Drawing.Size(20, 20); + browser.Name = "webBrowser1"; + browser.TabIndex = 1; + browser.Dock = DockStyle.Fill; + panel1.Controls.Add(browser); + } + + private Timer _tokenTimer = new Timer(); + private Timer _translationTimer = new Timer(); + private DateTime _expiresAt; + + private async void btnAuthenticate_Click(object sender, EventArgs e) + { + if (string.IsNullOrWhiteSpace(txtClientId.Text) || string.IsNullOrWhiteSpace(txtClientSecret.Text)) return; + + // get the access token + TwoLeggedApi oAuth = new TwoLeggedApi(); + dynamic token = await oAuth.AuthenticateAsync( + txtClientId.Text, + txtClientSecret.Text, + oAuthConstants.CLIENT_CREDENTIALS, + new Scope[] { Scope.BucketRead, Scope.BucketCreate, Scope.DataRead, Scope.DataWrite }); + txtAccessToken.Text = token.access_token; + _expiresAt = DateTime.Now.AddSeconds(token.expires_in); + + // keep track on time + _tokenTimer.Tick += new EventHandler(tickTokenTimer); + _tokenTimer.Interval = 1000; + _tokenTimer.Enabled = true; + + btnRefreshToken_Click(null, null); + } + + void tickTokenTimer(object sender, EventArgs e) + { + // update the time left on the access token + double secondsLeft = (_expiresAt - DateTime.Now).TotalSeconds; + txtTimeout.Text = secondsLeft.ToString("0"); + txtTimeout.BackColor = (secondsLeft < 60 ? System.Drawing.Color.Red : System.Drawing.SystemColors.Control); + } + + private string AccessToken + { + get + { + return txtAccessToken.Text; + } + } + + private async void btnRefreshToken_Click(object sender, EventArgs e) + { + treeBuckets.Nodes.Clear(); + + BucketsApi bucketApi = new BucketsApi(); + bucketApi.Configuration.AccessToken = AccessToken; + + // control GetBucket pagination + string lastBucket = null; + int itemCount = 0; + + // get buckets until returned list length < 100 + do + { + dynamic buckets = await bucketApi.GetBucketsAsync(null, 100, lastBucket); + itemCount += buckets.items.Count; + + foreach (KeyValuePair bucket in new DynamicDictionaryItems(buckets.items)) + { + TreeNode nodeBucket = new TreeNode(bucket.Value.bucketKey); + nodeBucket.Tag = bucket.Value.bucketKey; + treeBuckets.Nodes.Add(nodeBucket); + + lastBucket = bucket.Value.bucketKey; // after the loop, this will contain the last bucketKey + } + } while ((itemCount % 100) == 0); // while GetBuckets returns 100, we need to get next page + + // for each bucket, show the objects + foreach (TreeNode n in treeBuckets.Nodes) + if (n != null) // async? + await ShowBucketObjects(n); + } + + private async Task ShowBucketObjects(TreeNode nodeBucket) + { + nodeBucket.Nodes.Clear(); + + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + + // show objects on the given TreeNode + var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag); + foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) + { + TreeNode nodeObject = new TreeNode(objInfo.Value.objectKey); + nodeObject.Tag = ((string)objInfo.Value.objectId).Base64Encode(); + nodeBucket.Nodes.Add(nodeObject); + } + } + + private const int UPLOAD_CHUNK_SIZE = 2; // Mb + + private async void btnUpload_Click(object sender, EventArgs e) + { + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 0) + { + MessageBox.Show("Please select a bucket", "Bucket required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string bucketKey = treeBuckets.SelectedNode.Text; + + // ask user to select file + OpenFileDialog formSelectFile = new OpenFileDialog(); + formSelectFile.Multiselect = false; + if (formSelectFile.ShowDialog() != DialogResult.OK) return; + string filePath = formSelectFile.FileName; + string objectKey = Path.GetFileName(filePath); + + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + + // get file size + long fileSize = (new FileInfo(filePath)).Length; + + // show progress bar for upload + progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; + progressBar.Show(); + progressBar.Value = 0; + progressBar.Minimum = 0; + progressBar.CustomText = "Preparing to upload file..."; + + // decide if upload direct or resumable (by chunks) + if (fileSize > UPLOAD_CHUNK_SIZE * 1024 * 1024) // upload in chunks + { + long chunkSize = 2 * 1024 * 1024; // 2 Mb + long numberOfChunks = (long)Math.Round((double)(fileSize / chunkSize)) + 1; + + progressBar.Maximum = (int)numberOfChunks; + + long start = 0; + chunkSize = (numberOfChunks > 1 ? chunkSize : fileSize); + long end = chunkSize; + string sessionId = Guid.NewGuid().ToString(); + + // upload one chunk at a time + using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open))) + { + for (int chunkIndex = 0; chunkIndex < numberOfChunks; chunkIndex++) + { + string range = string.Format("bytes {0}-{1}/{2}", start, end, fileSize); + + long numberOfBytes = chunkSize + 1; + byte[] fileBytes = new byte[numberOfBytes]; + MemoryStream memoryStream = new MemoryStream(fileBytes); + reader.BaseStream.Seek((int)start, SeekOrigin.Begin); + int count = reader.Read(fileBytes, 0, (int)numberOfBytes); + memoryStream.Write(fileBytes, 0, (int)numberOfBytes); + memoryStream.Position = 0; + + dynamic chunkUploadResponse = await objects.UploadChunkAsync(bucketKey, objectKey, (int)numberOfBytes, range, sessionId, memoryStream); + + start = end + 1; + chunkSize = ((start + chunkSize > fileSize) ? fileSize - start - 1 : chunkSize); + end = start + chunkSize; + + progressBar.CustomText = string.Format("{0} Mb uploaded...", (chunkIndex * chunkSize) / 1024 / 1024); + progressBar.Value = chunkIndex; + } + } + } + else // upload in a single call + { + using (StreamReader streamReader = new StreamReader(filePath)) + { + progressBar.Value = 50; // random... + progressBar.Maximum = 100; + dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, + objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, + "application/octet-stream"); + } + + } + + progressBar.Hide(); + await ShowBucketObjects(treeBuckets.SelectedNode); + treeBuckets.SelectedNode.Expand(); + } + + private void Form1_Load(object sender, EventArgs e) + { + // authenticate when starts + btnAuthenticate_Click(null, null); + } + + private void btnTranslate_Click(object sender, EventArgs e) + { + // show menu with translation options + // ToDo: include other translation formats + menuTranslate.Items.Clear(); + menuTranslate.Items.Add("Viewer (SVF)", null, onClickTranslate); + menuTranslate.Show(btnTranslate, new Point(0, btnTranslate.Height)); + } + + private async void onClickTranslate(object sender, EventArgs e) + { + // for now, just one translation at a time + if (_translationTimer.Enabled) return; + + // check level 1 of objects + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string urn = (string)treeBuckets.SelectedNode.Tag; + + // prepare a SVF translation + List outputs = new List() + { + new JobPayloadItem( + JobPayloadItem.TypeEnum.Svf, + new List() + { + JobPayloadItem.ViewsEnum._2d, + JobPayloadItem.ViewsEnum._3d + }) + }; + JobPayload job; + //if (string.IsNullOrEmpty(objModel.rootFilename)) + job = new JobPayload(new JobPayloadInput(urn), new JobPayloadOutput(outputs)); + //else + // job = new JobPayload(new JobPayloadInput(objModel.objectKey, true, objModel.rootFilename), new JobPayloadOutput(outputs)); + + // start progress bar for translation + progressBar.Show(); + progressBar.Value = 0; + progressBar.Minimum = 0; + progressBar.Maximum = 100; + progressBar.CustomText = "Starting translation job..."; + + // start translation job + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = AccessToken; + dynamic jobPosted = await derivative.TranslateAsync(job, true); + + // start a monitor job to follow the translation + _translationTimer.Tick += new EventHandler(isTranslationReady); + _translationTimer.Tag = urn; + _translationTimer.Interval = 5000; + _translationTimer.Enabled = true; + } + + private async void isTranslationReady(object sender, EventArgs e) + { + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = AccessToken; + + // get the translation manifest + dynamic manifest = await derivative.GetManifestAsync((string)_translationTimer.Tag); + int progress = (string.IsNullOrWhiteSpace(Regex.Match(manifest.progress, @"\d+").Value) ? 100 : Int32.Parse(Regex.Match(manifest.progress, @"\d+").Value)); + + // for better UX, show a small number of progress (instead zero) + progressBar.Value = (progress == 0 ? 10 : progress); + progressBar.CustomText = string.Format("Translation in progress: {0}", progress); + Debug.WriteLine(progress); + + // if ready, hide everything + if (progress >= 100) + { + progressBar.Hide(); + _translationTimer.Enabled = false; + } + } + + private async void btnDeleteObject_Click(object sender, EventArgs e) + { + // treeBuckets level 1 are for Objects + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (MessageBox.Show("This objects will be permantly delete, confirm?", "Are you sure?", + MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + + // call API to delete object on the bucket + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + await objects.DeleteObjectAsync((string)treeBuckets.SelectedNode.Parent.Tag, (string)treeBuckets.SelectedNode.Text); + await ShowBucketObjects(treeBuckets.SelectedNode.Parent); + } + + private void Form1_FormClosing(object sender, FormClosingEventArgs e) + { + // required by CefSharp Browser + Cef.Shutdown(); + } + + private void treeBuckets_AfterSelect(object sender, TreeViewEventArgs e) + { + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) return; + + // this basic HTML page to show the model passing URN & Access Token + browser.Load(string.Format("file:///HTML/Viewer.html?URN={0}&Token={1}", treeBuckets.SelectedNode.Tag, AccessToken)); + } + + private async void btnCreateBucket_Click(object sender, EventArgs e) + { + string bucketKey = string.Empty; + if (Prompt.ShowDialog("Enter bucket name: ", "Create new bucket", txtClientId.Text.ToLower() + DateTime.Now.Ticks.ToString(), out bucketKey) == DialogResult.OK) + { + BucketsApi buckets = new BucketsApi(); + buckets.Configuration.AccessToken = AccessToken; + PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey.ToLower(), null, PostBucketsPayload.PolicyKeyEnum.Transient); + await buckets.CreateBucketAsync(bucketPayload); + + btnRefreshToken_Click(null, null); + } + } + + private void btnShowDevTools_Click(object sender, EventArgs e) + { + browser.ShowDevTools(); + } + + private async void btnDownloadSVF_Click(object sender, EventArgs e) + { + // ensure the selected node is an object and get its URN + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string urn = (string)treeBuckets.SelectedNode.Tag; + + // select a folder to download the files + string folderPath = string.Empty; + using (var fbd = new FolderBrowserDialog()) + { + if (fbd.ShowDialog() != DialogResult.OK || string.IsNullOrWhiteSpace(fbd.SelectedPath)) return; + folderPath = fbd.SelectedPath; + folderPath = Path.Combine(folderPath, treeBuckets.SelectedNode.Text); + if (Directory.Exists(folderPath)) Directory.Delete(folderPath, true); + Directory.CreateDirectory(folderPath); + } + + // prepare the UI + progressBar.Show(); + progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; + progressBar.Value = 0; + progressBar.CustomText = "Starting extraction..."; + + // get the list of resources to download + List resourcesToDownload = await ForgeUtils.Derivatives.ExtractSVFAsync(urn, AccessToken); + + // update the UI + progressBar.Minimum = 0; + progressBar.Maximum = resourcesToDownload.Count; + progressBar.Step = 1; + + IRestClient client = new RestClient("https://developer.api.autodesk.com/"); + foreach (ForgeUtils.Derivatives.Resource resource in resourcesToDownload) + { + progressBar.PerformStep(); + progressBar.CustomText = "Downloading " + resource.FileName; + + // prepare the GET to download the file + RestRequest request = new RestRequest(resource.RemotePath, Method.GET); + request.AddHeader("Authorization", "Bearer " + AccessToken); + request.AddHeader("Accept-Encoding", "gzip, deflate"); + IRestResponse response = await client.ExecuteTaskAsync(request); + + if (response.StatusCode != System.Net.HttpStatusCode.OK) + { + // something went wrong with this file... + MessageBox.Show(string.Format("Error downloading {0}: {1}", + resource.FileName, response.StatusCode.ToString())); + + // any other action? + } + else + { + // combine with selected local path + string pathToSave = Path.Combine(folderPath, resource.LocalPath); + // ensure local dir exists + Directory.CreateDirectory(Path.GetDirectoryName(pathToSave)); + // save file + File.WriteAllBytes(pathToSave, response.RawBytes); + } + } + + progressBar.Hide(); + } + + private void btnJavaScript_Click(object sender, EventArgs e) + { + Tools.JSEditor editor = new Tools.JSEditor(this.browser); + editor.Show(); + } + } +} diff --git a/bucket.manager/Utils/CustomProgress.cs b/bucket.manager/Utils/CustomProgress.cs index c1702c3..36afdb3 100644 --- a/bucket.manager/Utils/CustomProgress.cs +++ b/bucket.manager/Utils/CustomProgress.cs @@ -12,7 +12,7 @@ public enum ProgressBarDisplayText CustomText } - class CustomProgressBar : ProgressBar + public class CustomProgressBar : ProgressBar { //Property to set to decide whether to print a % or Text public ProgressBarDisplayText DisplayStyle { get; set; } diff --git a/bucket.manager/bucket.manager.csproj b/bucket.manager/bucket.manager.csproj index 83b0603..aff624f 100644 --- a/bucket.manager/bucket.manager.csproj +++ b/bucket.manager/bucket.manager.csproj @@ -104,6 +104,12 @@ + + Form + + + DisplayText.cs + Form @@ -124,6 +130,9 @@ Component + + DisplayText.cs + Form1.cs From 65112cbe5fcfb3b55524dbf03890972e4f2786e3 Mon Sep 17 00:00:00 2001 From: JayH Date: Sun, 23 Feb 2020 14:29:54 -0500 Subject: [PATCH 2/3] Revert "Fixed issue with object paging so see all objects in bucket (the issue is still probably in the bucket paging)." This reverts commit acf73dafce3b32be5ac52e6e399c86cb86aacdf8. --- bucket.manager/DisplayText.Designer.cs | 77 ----- bucket.manager/DisplayText.cs | 31 -- bucket.manager/DisplayText.resx | 120 ------- bucket.manager/Form1.Designer.cs | 88 ++--- bucket.manager/Form1.cs | 62 +--- bucket.manager/Form1.cs.bak | 455 ------------------------- bucket.manager/Utils/CustomProgress.cs | 2 +- bucket.manager/bucket.manager.csproj | 9 - 8 files changed, 31 insertions(+), 813 deletions(-) delete mode 100644 bucket.manager/DisplayText.Designer.cs delete mode 100644 bucket.manager/DisplayText.cs delete mode 100644 bucket.manager/DisplayText.resx delete mode 100644 bucket.manager/Form1.cs.bak diff --git a/bucket.manager/DisplayText.Designer.cs b/bucket.manager/DisplayText.Designer.cs deleted file mode 100644 index 3740fdf..0000000 --- a/bucket.manager/DisplayText.Designer.cs +++ /dev/null @@ -1,77 +0,0 @@ -namespace bucket.manager -{ - partial class DisplayText - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.tbText = new System.Windows.Forms.TextBox(); - this.btnClose = new System.Windows.Forms.Button(); - this.SuspendLayout(); - // - // tbText - // - this.tbText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.tbText.Location = new System.Drawing.Point(2, 3); - this.tbText.Multiline = true; - this.tbText.Name = "tbText"; - this.tbText.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.tbText.Size = new System.Drawing.Size(752, 375); - this.tbText.TabIndex = 0; - // - // btnClose - // - this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.btnClose.Location = new System.Drawing.Point(12, 386); - this.btnClose.Name = "btnClose"; - this.btnClose.Size = new System.Drawing.Size(75, 23); - this.btnClose.TabIndex = 1; - this.btnClose.Text = "Close"; - this.btnClose.UseVisualStyleBackColor = true; - this.btnClose.Click += new System.EventHandler(this.btnClose_Click); - // - // DisplayText - // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(757, 421); - this.Controls.Add(this.btnClose); - this.Controls.Add(this.tbText); - this.Name = "DisplayText"; - this.Text = "DisplayText"; - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - private System.Windows.Forms.TextBox tbText; - private System.Windows.Forms.Button btnClose; - } -} \ No newline at end of file diff --git a/bucket.manager/DisplayText.cs b/bucket.manager/DisplayText.cs deleted file mode 100644 index 92923e1..0000000 --- a/bucket.manager/DisplayText.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace bucket.manager -{ - public partial class DisplayText : Form - { - public DisplayText() - { - InitializeComponent(); - } - - public DisplayText(string theText) - { - InitializeComponent(); - this.tbText.Text = theText; - } - - private void btnClose_Click(object sender, EventArgs e) - { - this.Close(); - } - } -} diff --git a/bucket.manager/DisplayText.resx b/bucket.manager/DisplayText.resx deleted file mode 100644 index 1af7de1..0000000 --- a/bucket.manager/DisplayText.resx +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/bucket.manager/Form1.Designer.cs b/bucket.manager/Form1.Designer.cs index bb1e14e..2e50816 100644 --- a/bucket.manager/Form1.Designer.cs +++ b/bucket.manager/Form1.Designer.cs @@ -67,10 +67,7 @@ private void InitializeComponent() this.btnShowDevTools = new System.Windows.Forms.Button(); this.btnDownloadSVF = new System.Windows.Forms.Button(); this.btnJavaScript = new System.Windows.Forms.Button(); - this.tbFilter = new System.Windows.Forms.TextBox(); - this.label3 = new System.Windows.Forms.Label(); this.progressBar = new bucket.manager.Utils.CustomProgressBar(); - this.btnManifest = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // @@ -78,9 +75,9 @@ private void InitializeComponent() // this.treeBuckets.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); - this.treeBuckets.Location = new System.Drawing.Point(12, 208); + this.treeBuckets.Location = new System.Drawing.Point(12, 182); this.treeBuckets.Name = "treeBuckets"; - this.treeBuckets.Size = new System.Drawing.Size(225, 393); + this.treeBuckets.Size = new System.Drawing.Size(225, 419); this.treeBuckets.TabIndex = 0; this.treeBuckets.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeBuckets_AfterSelect); // @@ -107,7 +104,7 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.label1); this.groupBox1.Location = new System.Drawing.Point(13, 13); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(1092, 76); + this.groupBox1.Size = new System.Drawing.Size(675, 76); this.groupBox1.TabIndex = 2; this.groupBox1.TabStop = false; this.groupBox1.Text = "Forge Credentials"; @@ -115,7 +112,7 @@ private void InitializeComponent() // txtTimeout // this.txtTimeout.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtTimeout.Location = new System.Drawing.Point(1000, 46); + this.txtTimeout.Location = new System.Drawing.Point(583, 46); this.txtTimeout.Name = "txtTimeout"; this.txtTimeout.ReadOnly = true; this.txtTimeout.Size = new System.Drawing.Size(86, 20); @@ -129,7 +126,7 @@ private void InitializeComponent() this.txtAccessToken.Location = new System.Drawing.Point(100, 46); this.txtAccessToken.Name = "txtAccessToken"; this.txtAccessToken.ReadOnly = true; - this.txtAccessToken.Size = new System.Drawing.Size(894, 20); + this.txtAccessToken.Size = new System.Drawing.Size(477, 20); this.txtAccessToken.TabIndex = 9; // // label4 @@ -144,7 +141,7 @@ private void InitializeComponent() // btnAuthenticate // this.btnAuthenticate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnAuthenticate.Location = new System.Drawing.Point(1000, 18); + this.btnAuthenticate.Location = new System.Drawing.Point(583, 18); this.btnAuthenticate.Name = "btnAuthenticate"; this.btnAuthenticate.Size = new System.Drawing.Size(86, 23); this.btnAuthenticate.TabIndex = 5; @@ -155,7 +152,7 @@ private void InitializeComponent() // txtClientSecret // this.txtClientSecret.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtClientSecret.Location = new System.Drawing.Point(801, 20); + this.txtClientSecret.Location = new System.Drawing.Point(384, 20); this.txtClientSecret.Name = "txtClientSecret"; this.txtClientSecret.PasswordChar = '*'; this.txtClientSecret.Size = new System.Drawing.Size(193, 20); @@ -165,7 +162,7 @@ private void InitializeComponent() // this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(754, 24); + this.label2.Location = new System.Drawing.Point(337, 24); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(41, 13); this.label2.TabIndex = 3; @@ -177,14 +174,14 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.txtClientId.Location = new System.Drawing.Point(35, 20); this.txtClientId.Name = "txtClientId"; - this.txtClientId.Size = new System.Drawing.Size(713, 20); + this.txtClientId.Size = new System.Drawing.Size(296, 20); this.txtClientId.TabIndex = 2; // // btnRefreshToken // - this.btnRefreshToken.Location = new System.Drawing.Point(12, 95); + this.btnRefreshToken.Location = new System.Drawing.Point(13, 95); this.btnRefreshToken.Name = "btnRefreshToken"; - this.btnRefreshToken.Size = new System.Drawing.Size(108, 23); + this.btnRefreshToken.Size = new System.Drawing.Size(121, 23); this.btnRefreshToken.TabIndex = 3; this.btnRefreshToken.Text = "Refresh buckets"; this.btnRefreshToken.UseVisualStyleBackColor = true; @@ -192,9 +189,9 @@ private void InitializeComponent() // // btnCreateBucket // - this.btnCreateBucket.Location = new System.Drawing.Point(129, 95); + this.btnCreateBucket.Location = new System.Drawing.Point(140, 95); this.btnCreateBucket.Name = "btnCreateBucket"; - this.btnCreateBucket.Size = new System.Drawing.Size(108, 23); + this.btnCreateBucket.Size = new System.Drawing.Size(97, 23); this.btnCreateBucket.TabIndex = 4; this.btnCreateBucket.Text = "Create Bucket"; this.btnCreateBucket.UseVisualStyleBackColor = true; @@ -202,9 +199,9 @@ private void InitializeComponent() // // btnUpload // - this.btnUpload.Location = new System.Drawing.Point(12, 150); + this.btnUpload.Location = new System.Drawing.Point(13, 153); this.btnUpload.Name = "btnUpload"; - this.btnUpload.Size = new System.Drawing.Size(108, 23); + this.btnUpload.Size = new System.Drawing.Size(93, 23); this.btnUpload.TabIndex = 5; this.btnUpload.Text = "Upload File"; this.btnUpload.UseVisualStyleBackColor = true; @@ -212,11 +209,11 @@ private void InitializeComponent() // // btnTranslate // - this.btnTranslate.Location = new System.Drawing.Point(12, 179); + this.btnTranslate.Location = new System.Drawing.Point(113, 153); this.btnTranslate.Name = "btnTranslate"; - this.btnTranslate.Size = new System.Drawing.Size(108, 23); + this.btnTranslate.Size = new System.Drawing.Size(124, 23); this.btnTranslate.TabIndex = 6; - this.btnTranslate.Text = "Translate File"; + this.btnTranslate.Text = "Translate file"; this.btnTranslate.UseVisualStyleBackColor = true; this.btnTranslate.Click += new System.EventHandler(this.btnTranslate_Click); // @@ -228,9 +225,9 @@ private void InitializeComponent() // // btnDeleteObject // - this.btnDeleteObject.Location = new System.Drawing.Point(129, 150); + this.btnDeleteObject.Location = new System.Drawing.Point(13, 124); this.btnDeleteObject.Name = "btnDeleteObject"; - this.btnDeleteObject.Size = new System.Drawing.Size(108, 23); + this.btnDeleteObject.Size = new System.Drawing.Size(103, 23); this.btnDeleteObject.TabIndex = 8; this.btnDeleteObject.Text = "Delete Object"; this.btnDeleteObject.UseVisualStyleBackColor = true; @@ -244,13 +241,13 @@ private void InitializeComponent() this.panel1.Location = new System.Drawing.Point(242, 95); this.panel1.Margin = new System.Windows.Forms.Padding(2); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(863, 477); + this.panel1.Size = new System.Drawing.Size(446, 477); this.panel1.TabIndex = 9; // // btnShowDevTools // this.btnShowDevTools.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnShowDevTools.Location = new System.Drawing.Point(1030, 577); + this.btnShowDevTools.Location = new System.Drawing.Point(613, 577); this.btnShowDevTools.Name = "btnShowDevTools"; this.btnShowDevTools.Size = new System.Drawing.Size(75, 23); this.btnShowDevTools.TabIndex = 10; @@ -261,7 +258,7 @@ private void InitializeComponent() // btnDownloadSVF // this.btnDownloadSVF.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnDownloadSVF.Location = new System.Drawing.Point(909, 577); + this.btnDownloadSVF.Location = new System.Drawing.Point(492, 577); this.btnDownloadSVF.Name = "btnDownloadSVF"; this.btnDownloadSVF.Size = new System.Drawing.Size(115, 23); this.btnDownloadSVF.TabIndex = 11; @@ -272,7 +269,7 @@ private void InitializeComponent() // btnJavaScript // this.btnJavaScript.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnJavaScript.Location = new System.Drawing.Point(828, 577); + this.btnJavaScript.Location = new System.Drawing.Point(411, 577); this.btnJavaScript.Name = "btnJavaScript"; this.btnJavaScript.Size = new System.Drawing.Size(75, 23); this.btnJavaScript.TabIndex = 12; @@ -280,22 +277,6 @@ private void InitializeComponent() this.btnJavaScript.UseVisualStyleBackColor = true; this.btnJavaScript.Click += new System.EventHandler(this.btnJavaScript_Click); // - // tbFilter - // - this.tbFilter.Location = new System.Drawing.Point(48, 124); - this.tbFilter.Name = "tbFilter"; - this.tbFilter.Size = new System.Drawing.Size(189, 20); - this.tbFilter.TabIndex = 13; - // - // label3 - // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(13, 128); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(29, 13); - this.label3.TabIndex = 14; - this.label3.Text = "Filter"; - // // progressBar // this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) @@ -304,28 +285,15 @@ private void InitializeComponent() this.progressBar.DisplayStyle = bucket.manager.Utils.ProgressBarDisplayText.Percentage; this.progressBar.Location = new System.Drawing.Point(12, 607); this.progressBar.Name = "progressBar"; - this.progressBar.Size = new System.Drawing.Size(1093, 23); + this.progressBar.Size = new System.Drawing.Size(676, 23); this.progressBar.TabIndex = 7; this.progressBar.Visible = false; // - // btnManifest - // - this.btnManifest.Location = new System.Drawing.Point(129, 179); - this.btnManifest.Name = "btnManifest"; - this.btnManifest.Size = new System.Drawing.Size(108, 23); - this.btnManifest.TabIndex = 15; - this.btnManifest.Text = "Show Manifest"; - this.btnManifest.UseVisualStyleBackColor = true; - this.btnManifest.Click += new System.EventHandler(this.btnManifest_Click); - // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(1117, 642); - this.Controls.Add(this.btnManifest); - this.Controls.Add(this.label3); - this.Controls.Add(this.tbFilter); + this.ClientSize = new System.Drawing.Size(700, 642); this.Controls.Add(this.btnJavaScript); this.Controls.Add(this.btnDownloadSVF); this.Controls.Add(this.btnShowDevTools); @@ -346,7 +314,6 @@ private void InitializeComponent() this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.ResumeLayout(false); - this.PerformLayout(); } @@ -373,9 +340,6 @@ private void InitializeComponent() private System.Windows.Forms.Button btnShowDevTools; private System.Windows.Forms.Button btnDownloadSVF; private System.Windows.Forms.Button btnJavaScript; - private System.Windows.Forms.TextBox tbFilter; - private System.Windows.Forms.Label label3; - private System.Windows.Forms.Button btnManifest; } } diff --git a/bucket.manager/Form1.cs b/bucket.manager/Form1.cs index c7b92dd..e0364b5 100644 --- a/bucket.manager/Form1.cs +++ b/bucket.manager/Form1.cs @@ -131,51 +131,23 @@ private async void btnRefreshToken_Click(object sender, EventArgs e) foreach (TreeNode n in treeBuckets.Nodes) if (n != null) // async? await ShowBucketObjects(n); - - treeBuckets.Sort(); } private async Task ShowBucketObjects(TreeNode nodeBucket) { - string filter = tbFilter.Text; - if (filter == "") filter = null; - nodeBucket.Nodes.Clear(); - // control GetBucket pagination - string lastNode = null; - int itemCount = 0; - ObjectsApi objects = new ObjectsApi(); objects.Configuration.AccessToken = AccessToken; // show objects on the given TreeNode - do - { - var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag, 100, filter, lastNode); //"24288A-1000" - itemCount += objectsList.items.Count; - if (itemCount == 0) break; - if (((DynamicJsonResponse)objectsList).Dictionary.ContainsKey("next") && objectsList.next != null) - { - lastNode = ((string)objectsList.next); - int start = lastNode.IndexOf("startAt=") + 8; - int end = lastNode.IndexOf("&limit="); - lastNode = Uri.UnescapeDataString(lastNode.Substring(start, end - start)); - } - else - { - lastNode = null; - } - + var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag); foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) { TreeNode nodeObject = new TreeNode(objInfo.Value.objectKey); nodeObject.Tag = ((string)objInfo.Value.objectId).Base64Encode(); nodeBucket.Nodes.Add(nodeObject); - } - if (lastNode == null) break; - } while ((itemCount % 100) == 0); } private const int UPLOAD_CHUNK_SIZE = 2; // Mb @@ -205,8 +177,8 @@ private async void btnUpload_Click(object sender, EventArgs e) // show progress bar for upload progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; progressBar.Show(); - progressBar.Minimum = 0; progressBar.Value = 0; + progressBar.Minimum = 0; progressBar.CustomText = "Preparing to upload file..."; // decide if upload direct or resumable (by chunks) @@ -252,8 +224,8 @@ private async void btnUpload_Click(object sender, EventArgs e) { using (StreamReader streamReader = new StreamReader(filePath)) { - progressBar.Maximum = 100; progressBar.Value = 50; // random... + progressBar.Maximum = 100; dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream"); @@ -281,32 +253,6 @@ private void btnTranslate_Click(object sender, EventArgs e) menuTranslate.Show(btnTranslate, new Point(0, btnTranslate.Height)); } - private void btnManifest_Click(object sender, EventArgs e) - { - // check level 1 of objects - if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) - { - MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - string urn = (string)treeBuckets.SelectedNode.Tag; - - DerivativesApi derivative = new DerivativesApi(); - derivative.Configuration.AccessToken = AccessToken; - try - { - string aManifest = derivative.GetManifest(urn).ToString(); - - using (var displayText = new DisplayText(aManifest)) - { - displayText.ShowDialog(); - } - } catch (Exception ex) - { - MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - private async void onClickTranslate(object sender, EventArgs e) { // for now, just one translation at a time @@ -339,9 +285,9 @@ private async void onClickTranslate(object sender, EventArgs e) // start progress bar for translation progressBar.Show(); + progressBar.Value = 0; progressBar.Minimum = 0; progressBar.Maximum = 100; - progressBar.Value = 0; progressBar.CustomText = "Starting translation job..."; // start translation job diff --git a/bucket.manager/Form1.cs.bak b/bucket.manager/Form1.cs.bak deleted file mode 100644 index d4c338a..0000000 --- a/bucket.manager/Form1.cs.bak +++ /dev/null @@ -1,455 +0,0 @@ -///////////////////////////////////////////////////////////////////// -// Copyright (c) Autodesk, Inc. All rights reserved -// Written by Forge Partner Development -// -// Permission to use, copy, modify, and distribute this software in -// object code form for any purpose and without fee is hereby granted, -// provided that the above copyright notice appears in all copies and -// that both that copyright notice and the limited warranty and -// restricted rights notice below appear in all supporting -// documentation. -// -// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. -// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF -// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. -// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE -// UNINTERRUPTED OR ERROR FREE. -///////////////////////////////////////////////////////////////////// - -using Autodesk.Forge; -using Autodesk.Forge.Model; -using bucket.manager.Utils; -using CefSharp; -using CefSharp.WinForms; -using RestSharp; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace bucket.manager -{ - public partial class Form1 : Form - { - public Form1() - { - InitializeComponent(); - InitBrowser(); - } - - public ChromiumWebBrowser browser; - - public void InitBrowser() - { - Cef.Initialize(new CefSettings()); - browser = new ChromiumWebBrowser("file:///HTML/Viewer.html"); // CefSharp needs a initial page... - - browser.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - browser.MinimumSize = new System.Drawing.Size(20, 20); - browser.Name = "webBrowser1"; - browser.TabIndex = 1; - browser.Dock = DockStyle.Fill; - panel1.Controls.Add(browser); - } - - private Timer _tokenTimer = new Timer(); - private Timer _translationTimer = new Timer(); - private DateTime _expiresAt; - - private async void btnAuthenticate_Click(object sender, EventArgs e) - { - if (string.IsNullOrWhiteSpace(txtClientId.Text) || string.IsNullOrWhiteSpace(txtClientSecret.Text)) return; - - // get the access token - TwoLeggedApi oAuth = new TwoLeggedApi(); - dynamic token = await oAuth.AuthenticateAsync( - txtClientId.Text, - txtClientSecret.Text, - oAuthConstants.CLIENT_CREDENTIALS, - new Scope[] { Scope.BucketRead, Scope.BucketCreate, Scope.DataRead, Scope.DataWrite }); - txtAccessToken.Text = token.access_token; - _expiresAt = DateTime.Now.AddSeconds(token.expires_in); - - // keep track on time - _tokenTimer.Tick += new EventHandler(tickTokenTimer); - _tokenTimer.Interval = 1000; - _tokenTimer.Enabled = true; - - btnRefreshToken_Click(null, null); - } - - void tickTokenTimer(object sender, EventArgs e) - { - // update the time left on the access token - double secondsLeft = (_expiresAt - DateTime.Now).TotalSeconds; - txtTimeout.Text = secondsLeft.ToString("0"); - txtTimeout.BackColor = (secondsLeft < 60 ? System.Drawing.Color.Red : System.Drawing.SystemColors.Control); - } - - private string AccessToken - { - get - { - return txtAccessToken.Text; - } - } - - private async void btnRefreshToken_Click(object sender, EventArgs e) - { - treeBuckets.Nodes.Clear(); - - BucketsApi bucketApi = new BucketsApi(); - bucketApi.Configuration.AccessToken = AccessToken; - - // control GetBucket pagination - string lastBucket = null; - int itemCount = 0; - - // get buckets until returned list length < 100 - do - { - dynamic buckets = await bucketApi.GetBucketsAsync(null, 100, lastBucket); - itemCount += buckets.items.Count; - - foreach (KeyValuePair bucket in new DynamicDictionaryItems(buckets.items)) - { - TreeNode nodeBucket = new TreeNode(bucket.Value.bucketKey); - nodeBucket.Tag = bucket.Value.bucketKey; - treeBuckets.Nodes.Add(nodeBucket); - - lastBucket = bucket.Value.bucketKey; // after the loop, this will contain the last bucketKey - } - } while ((itemCount % 100) == 0); // while GetBuckets returns 100, we need to get next page - - // for each bucket, show the objects - foreach (TreeNode n in treeBuckets.Nodes) - if (n != null) // async? - await ShowBucketObjects(n); - } - - private async Task ShowBucketObjects(TreeNode nodeBucket) - { - nodeBucket.Nodes.Clear(); - - ObjectsApi objects = new ObjectsApi(); - objects.Configuration.AccessToken = AccessToken; - - // show objects on the given TreeNode - var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag); - foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) - { - TreeNode nodeObject = new TreeNode(objInfo.Value.objectKey); - nodeObject.Tag = ((string)objInfo.Value.objectId).Base64Encode(); - nodeBucket.Nodes.Add(nodeObject); - } - } - - private const int UPLOAD_CHUNK_SIZE = 2; // Mb - - private async void btnUpload_Click(object sender, EventArgs e) - { - if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 0) - { - MessageBox.Show("Please select a bucket", "Bucket required", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - string bucketKey = treeBuckets.SelectedNode.Text; - - // ask user to select file - OpenFileDialog formSelectFile = new OpenFileDialog(); - formSelectFile.Multiselect = false; - if (formSelectFile.ShowDialog() != DialogResult.OK) return; - string filePath = formSelectFile.FileName; - string objectKey = Path.GetFileName(filePath); - - ObjectsApi objects = new ObjectsApi(); - objects.Configuration.AccessToken = AccessToken; - - // get file size - long fileSize = (new FileInfo(filePath)).Length; - - // show progress bar for upload - progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; - progressBar.Show(); - progressBar.Value = 0; - progressBar.Minimum = 0; - progressBar.CustomText = "Preparing to upload file..."; - - // decide if upload direct or resumable (by chunks) - if (fileSize > UPLOAD_CHUNK_SIZE * 1024 * 1024) // upload in chunks - { - long chunkSize = 2 * 1024 * 1024; // 2 Mb - long numberOfChunks = (long)Math.Round((double)(fileSize / chunkSize)) + 1; - - progressBar.Maximum = (int)numberOfChunks; - - long start = 0; - chunkSize = (numberOfChunks > 1 ? chunkSize : fileSize); - long end = chunkSize; - string sessionId = Guid.NewGuid().ToString(); - - // upload one chunk at a time - using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open))) - { - for (int chunkIndex = 0; chunkIndex < numberOfChunks; chunkIndex++) - { - string range = string.Format("bytes {0}-{1}/{2}", start, end, fileSize); - - long numberOfBytes = chunkSize + 1; - byte[] fileBytes = new byte[numberOfBytes]; - MemoryStream memoryStream = new MemoryStream(fileBytes); - reader.BaseStream.Seek((int)start, SeekOrigin.Begin); - int count = reader.Read(fileBytes, 0, (int)numberOfBytes); - memoryStream.Write(fileBytes, 0, (int)numberOfBytes); - memoryStream.Position = 0; - - dynamic chunkUploadResponse = await objects.UploadChunkAsync(bucketKey, objectKey, (int)numberOfBytes, range, sessionId, memoryStream); - - start = end + 1; - chunkSize = ((start + chunkSize > fileSize) ? fileSize - start - 1 : chunkSize); - end = start + chunkSize; - - progressBar.CustomText = string.Format("{0} Mb uploaded...", (chunkIndex * chunkSize) / 1024 / 1024); - progressBar.Value = chunkIndex; - } - } - } - else // upload in a single call - { - using (StreamReader streamReader = new StreamReader(filePath)) - { - progressBar.Value = 50; // random... - progressBar.Maximum = 100; - dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, - objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, - "application/octet-stream"); - } - - } - - progressBar.Hide(); - await ShowBucketObjects(treeBuckets.SelectedNode); - treeBuckets.SelectedNode.Expand(); - } - - private void Form1_Load(object sender, EventArgs e) - { - // authenticate when starts - btnAuthenticate_Click(null, null); - } - - private void btnTranslate_Click(object sender, EventArgs e) - { - // show menu with translation options - // ToDo: include other translation formats - menuTranslate.Items.Clear(); - menuTranslate.Items.Add("Viewer (SVF)", null, onClickTranslate); - menuTranslate.Show(btnTranslate, new Point(0, btnTranslate.Height)); - } - - private async void onClickTranslate(object sender, EventArgs e) - { - // for now, just one translation at a time - if (_translationTimer.Enabled) return; - - // check level 1 of objects - if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) - { - MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - string urn = (string)treeBuckets.SelectedNode.Tag; - - // prepare a SVF translation - List outputs = new List() - { - new JobPayloadItem( - JobPayloadItem.TypeEnum.Svf, - new List() - { - JobPayloadItem.ViewsEnum._2d, - JobPayloadItem.ViewsEnum._3d - }) - }; - JobPayload job; - //if (string.IsNullOrEmpty(objModel.rootFilename)) - job = new JobPayload(new JobPayloadInput(urn), new JobPayloadOutput(outputs)); - //else - // job = new JobPayload(new JobPayloadInput(objModel.objectKey, true, objModel.rootFilename), new JobPayloadOutput(outputs)); - - // start progress bar for translation - progressBar.Show(); - progressBar.Value = 0; - progressBar.Minimum = 0; - progressBar.Maximum = 100; - progressBar.CustomText = "Starting translation job..."; - - // start translation job - DerivativesApi derivative = new DerivativesApi(); - derivative.Configuration.AccessToken = AccessToken; - dynamic jobPosted = await derivative.TranslateAsync(job, true); - - // start a monitor job to follow the translation - _translationTimer.Tick += new EventHandler(isTranslationReady); - _translationTimer.Tag = urn; - _translationTimer.Interval = 5000; - _translationTimer.Enabled = true; - } - - private async void isTranslationReady(object sender, EventArgs e) - { - DerivativesApi derivative = new DerivativesApi(); - derivative.Configuration.AccessToken = AccessToken; - - // get the translation manifest - dynamic manifest = await derivative.GetManifestAsync((string)_translationTimer.Tag); - int progress = (string.IsNullOrWhiteSpace(Regex.Match(manifest.progress, @"\d+").Value) ? 100 : Int32.Parse(Regex.Match(manifest.progress, @"\d+").Value)); - - // for better UX, show a small number of progress (instead zero) - progressBar.Value = (progress == 0 ? 10 : progress); - progressBar.CustomText = string.Format("Translation in progress: {0}", progress); - Debug.WriteLine(progress); - - // if ready, hide everything - if (progress >= 100) - { - progressBar.Hide(); - _translationTimer.Enabled = false; - } - } - - private async void btnDeleteObject_Click(object sender, EventArgs e) - { - // treeBuckets level 1 are for Objects - if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) - { - MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - if (MessageBox.Show("This objects will be permantly delete, confirm?", "Are you sure?", - MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) - return; - - // call API to delete object on the bucket - ObjectsApi objects = new ObjectsApi(); - objects.Configuration.AccessToken = AccessToken; - await objects.DeleteObjectAsync((string)treeBuckets.SelectedNode.Parent.Tag, (string)treeBuckets.SelectedNode.Text); - await ShowBucketObjects(treeBuckets.SelectedNode.Parent); - } - - private void Form1_FormClosing(object sender, FormClosingEventArgs e) - { - // required by CefSharp Browser - Cef.Shutdown(); - } - - private void treeBuckets_AfterSelect(object sender, TreeViewEventArgs e) - { - if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) return; - - // this basic HTML page to show the model passing URN & Access Token - browser.Load(string.Format("file:///HTML/Viewer.html?URN={0}&Token={1}", treeBuckets.SelectedNode.Tag, AccessToken)); - } - - private async void btnCreateBucket_Click(object sender, EventArgs e) - { - string bucketKey = string.Empty; - if (Prompt.ShowDialog("Enter bucket name: ", "Create new bucket", txtClientId.Text.ToLower() + DateTime.Now.Ticks.ToString(), out bucketKey) == DialogResult.OK) - { - BucketsApi buckets = new BucketsApi(); - buckets.Configuration.AccessToken = AccessToken; - PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey.ToLower(), null, PostBucketsPayload.PolicyKeyEnum.Transient); - await buckets.CreateBucketAsync(bucketPayload); - - btnRefreshToken_Click(null, null); - } - } - - private void btnShowDevTools_Click(object sender, EventArgs e) - { - browser.ShowDevTools(); - } - - private async void btnDownloadSVF_Click(object sender, EventArgs e) - { - // ensure the selected node is an object and get its URN - if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) - { - MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - string urn = (string)treeBuckets.SelectedNode.Tag; - - // select a folder to download the files - string folderPath = string.Empty; - using (var fbd = new FolderBrowserDialog()) - { - if (fbd.ShowDialog() != DialogResult.OK || string.IsNullOrWhiteSpace(fbd.SelectedPath)) return; - folderPath = fbd.SelectedPath; - folderPath = Path.Combine(folderPath, treeBuckets.SelectedNode.Text); - if (Directory.Exists(folderPath)) Directory.Delete(folderPath, true); - Directory.CreateDirectory(folderPath); - } - - // prepare the UI - progressBar.Show(); - progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; - progressBar.Value = 0; - progressBar.CustomText = "Starting extraction..."; - - // get the list of resources to download - List resourcesToDownload = await ForgeUtils.Derivatives.ExtractSVFAsync(urn, AccessToken); - - // update the UI - progressBar.Minimum = 0; - progressBar.Maximum = resourcesToDownload.Count; - progressBar.Step = 1; - - IRestClient client = new RestClient("https://developer.api.autodesk.com/"); - foreach (ForgeUtils.Derivatives.Resource resource in resourcesToDownload) - { - progressBar.PerformStep(); - progressBar.CustomText = "Downloading " + resource.FileName; - - // prepare the GET to download the file - RestRequest request = new RestRequest(resource.RemotePath, Method.GET); - request.AddHeader("Authorization", "Bearer " + AccessToken); - request.AddHeader("Accept-Encoding", "gzip, deflate"); - IRestResponse response = await client.ExecuteTaskAsync(request); - - if (response.StatusCode != System.Net.HttpStatusCode.OK) - { - // something went wrong with this file... - MessageBox.Show(string.Format("Error downloading {0}: {1}", - resource.FileName, response.StatusCode.ToString())); - - // any other action? - } - else - { - // combine with selected local path - string pathToSave = Path.Combine(folderPath, resource.LocalPath); - // ensure local dir exists - Directory.CreateDirectory(Path.GetDirectoryName(pathToSave)); - // save file - File.WriteAllBytes(pathToSave, response.RawBytes); - } - } - - progressBar.Hide(); - } - - private void btnJavaScript_Click(object sender, EventArgs e) - { - Tools.JSEditor editor = new Tools.JSEditor(this.browser); - editor.Show(); - } - } -} diff --git a/bucket.manager/Utils/CustomProgress.cs b/bucket.manager/Utils/CustomProgress.cs index 36afdb3..c1702c3 100644 --- a/bucket.manager/Utils/CustomProgress.cs +++ b/bucket.manager/Utils/CustomProgress.cs @@ -12,7 +12,7 @@ public enum ProgressBarDisplayText CustomText } - public class CustomProgressBar : ProgressBar + class CustomProgressBar : ProgressBar { //Property to set to decide whether to print a % or Text public ProgressBarDisplayText DisplayStyle { get; set; } diff --git a/bucket.manager/bucket.manager.csproj b/bucket.manager/bucket.manager.csproj index aff624f..83b0603 100644 --- a/bucket.manager/bucket.manager.csproj +++ b/bucket.manager/bucket.manager.csproj @@ -104,12 +104,6 @@ - - Form - - - DisplayText.cs - Form @@ -130,9 +124,6 @@ Component - - DisplayText.cs - Form1.cs From 43296e97a84ca925a3142dc277d0149f125dd307 Mon Sep 17 00:00:00 2001 From: JayH Date: Sun, 23 Feb 2020 14:52:11 -0500 Subject: [PATCH 3/3] Fixed issue with object paging so see all objects in bucket (the issue is still probably in the bucket paging). Added a sort to the treeview. Added a filter input text field that can be used to filter the objects in the buckets when the refresh buckets button is pressed. Added a show manifest button so you can see the object status, and more importantly, the reason if the translate failed. --- bucket.manager/DisplayText.Designer.cs | 77 ++++ bucket.manager/DisplayText.cs | 31 ++ bucket.manager/DisplayText.resx | 120 ++++++ bucket.manager/Form1.Designer.cs | 88 ++-- bucket.manager/Form1.Designer.cs.bak | 345 ++++++++++++++++ bucket.manager/Form1.cs | 72 +++- bucket.manager/Form1.cs.bak | 455 +++++++++++++++++++++ bucket.manager/Utils/CustomProgress.cs | 2 +- bucket.manager/Utils/CustomProgress.cs.bak | 61 +++ bucket.manager/bucket.manager.csproj | 9 + bucket.manager/bucket.manager.csproj.bak | 180 ++++++++ 11 files changed, 1404 insertions(+), 36 deletions(-) create mode 100644 bucket.manager/DisplayText.Designer.cs create mode 100644 bucket.manager/DisplayText.cs create mode 100644 bucket.manager/DisplayText.resx create mode 100644 bucket.manager/Form1.Designer.cs.bak create mode 100644 bucket.manager/Form1.cs.bak create mode 100644 bucket.manager/Utils/CustomProgress.cs.bak create mode 100644 bucket.manager/bucket.manager.csproj.bak diff --git a/bucket.manager/DisplayText.Designer.cs b/bucket.manager/DisplayText.Designer.cs new file mode 100644 index 0000000..3740fdf --- /dev/null +++ b/bucket.manager/DisplayText.Designer.cs @@ -0,0 +1,77 @@ +namespace bucket.manager +{ + partial class DisplayText + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tbText = new System.Windows.Forms.TextBox(); + this.btnClose = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // tbText + // + this.tbText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbText.Location = new System.Drawing.Point(2, 3); + this.tbText.Multiline = true; + this.tbText.Name = "tbText"; + this.tbText.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.tbText.Size = new System.Drawing.Size(752, 375); + this.tbText.TabIndex = 0; + // + // btnClose + // + this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btnClose.Location = new System.Drawing.Point(12, 386); + this.btnClose.Name = "btnClose"; + this.btnClose.Size = new System.Drawing.Size(75, 23); + this.btnClose.TabIndex = 1; + this.btnClose.Text = "Close"; + this.btnClose.UseVisualStyleBackColor = true; + this.btnClose.Click += new System.EventHandler(this.btnClose_Click); + // + // DisplayText + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(757, 421); + this.Controls.Add(this.btnClose); + this.Controls.Add(this.tbText); + this.Name = "DisplayText"; + this.Text = "DisplayText"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox tbText; + private System.Windows.Forms.Button btnClose; + } +} \ No newline at end of file diff --git a/bucket.manager/DisplayText.cs b/bucket.manager/DisplayText.cs new file mode 100644 index 0000000..92923e1 --- /dev/null +++ b/bucket.manager/DisplayText.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace bucket.manager +{ + public partial class DisplayText : Form + { + public DisplayText() + { + InitializeComponent(); + } + + public DisplayText(string theText) + { + InitializeComponent(); + this.tbText.Text = theText; + } + + private void btnClose_Click(object sender, EventArgs e) + { + this.Close(); + } + } +} diff --git a/bucket.manager/DisplayText.resx b/bucket.manager/DisplayText.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/bucket.manager/DisplayText.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/bucket.manager/Form1.Designer.cs b/bucket.manager/Form1.Designer.cs index 2e50816..bb1e14e 100644 --- a/bucket.manager/Form1.Designer.cs +++ b/bucket.manager/Form1.Designer.cs @@ -67,7 +67,10 @@ private void InitializeComponent() this.btnShowDevTools = new System.Windows.Forms.Button(); this.btnDownloadSVF = new System.Windows.Forms.Button(); this.btnJavaScript = new System.Windows.Forms.Button(); + this.tbFilter = new System.Windows.Forms.TextBox(); + this.label3 = new System.Windows.Forms.Label(); this.progressBar = new bucket.manager.Utils.CustomProgressBar(); + this.btnManifest = new System.Windows.Forms.Button(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // @@ -75,9 +78,9 @@ private void InitializeComponent() // this.treeBuckets.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); - this.treeBuckets.Location = new System.Drawing.Point(12, 182); + this.treeBuckets.Location = new System.Drawing.Point(12, 208); this.treeBuckets.Name = "treeBuckets"; - this.treeBuckets.Size = new System.Drawing.Size(225, 419); + this.treeBuckets.Size = new System.Drawing.Size(225, 393); this.treeBuckets.TabIndex = 0; this.treeBuckets.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeBuckets_AfterSelect); // @@ -104,7 +107,7 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.label1); this.groupBox1.Location = new System.Drawing.Point(13, 13); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Size = new System.Drawing.Size(675, 76); + this.groupBox1.Size = new System.Drawing.Size(1092, 76); this.groupBox1.TabIndex = 2; this.groupBox1.TabStop = false; this.groupBox1.Text = "Forge Credentials"; @@ -112,7 +115,7 @@ private void InitializeComponent() // txtTimeout // this.txtTimeout.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtTimeout.Location = new System.Drawing.Point(583, 46); + this.txtTimeout.Location = new System.Drawing.Point(1000, 46); this.txtTimeout.Name = "txtTimeout"; this.txtTimeout.ReadOnly = true; this.txtTimeout.Size = new System.Drawing.Size(86, 20); @@ -126,7 +129,7 @@ private void InitializeComponent() this.txtAccessToken.Location = new System.Drawing.Point(100, 46); this.txtAccessToken.Name = "txtAccessToken"; this.txtAccessToken.ReadOnly = true; - this.txtAccessToken.Size = new System.Drawing.Size(477, 20); + this.txtAccessToken.Size = new System.Drawing.Size(894, 20); this.txtAccessToken.TabIndex = 9; // // label4 @@ -141,7 +144,7 @@ private void InitializeComponent() // btnAuthenticate // this.btnAuthenticate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.btnAuthenticate.Location = new System.Drawing.Point(583, 18); + this.btnAuthenticate.Location = new System.Drawing.Point(1000, 18); this.btnAuthenticate.Name = "btnAuthenticate"; this.btnAuthenticate.Size = new System.Drawing.Size(86, 23); this.btnAuthenticate.TabIndex = 5; @@ -152,7 +155,7 @@ private void InitializeComponent() // txtClientSecret // this.txtClientSecret.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.txtClientSecret.Location = new System.Drawing.Point(384, 20); + this.txtClientSecret.Location = new System.Drawing.Point(801, 20); this.txtClientSecret.Name = "txtClientSecret"; this.txtClientSecret.PasswordChar = '*'; this.txtClientSecret.Size = new System.Drawing.Size(193, 20); @@ -162,7 +165,7 @@ private void InitializeComponent() // this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(337, 24); + this.label2.Location = new System.Drawing.Point(754, 24); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(41, 13); this.label2.TabIndex = 3; @@ -174,14 +177,14 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.txtClientId.Location = new System.Drawing.Point(35, 20); this.txtClientId.Name = "txtClientId"; - this.txtClientId.Size = new System.Drawing.Size(296, 20); + this.txtClientId.Size = new System.Drawing.Size(713, 20); this.txtClientId.TabIndex = 2; // // btnRefreshToken // - this.btnRefreshToken.Location = new System.Drawing.Point(13, 95); + this.btnRefreshToken.Location = new System.Drawing.Point(12, 95); this.btnRefreshToken.Name = "btnRefreshToken"; - this.btnRefreshToken.Size = new System.Drawing.Size(121, 23); + this.btnRefreshToken.Size = new System.Drawing.Size(108, 23); this.btnRefreshToken.TabIndex = 3; this.btnRefreshToken.Text = "Refresh buckets"; this.btnRefreshToken.UseVisualStyleBackColor = true; @@ -189,9 +192,9 @@ private void InitializeComponent() // // btnCreateBucket // - this.btnCreateBucket.Location = new System.Drawing.Point(140, 95); + this.btnCreateBucket.Location = new System.Drawing.Point(129, 95); this.btnCreateBucket.Name = "btnCreateBucket"; - this.btnCreateBucket.Size = new System.Drawing.Size(97, 23); + this.btnCreateBucket.Size = new System.Drawing.Size(108, 23); this.btnCreateBucket.TabIndex = 4; this.btnCreateBucket.Text = "Create Bucket"; this.btnCreateBucket.UseVisualStyleBackColor = true; @@ -199,9 +202,9 @@ private void InitializeComponent() // // btnUpload // - this.btnUpload.Location = new System.Drawing.Point(13, 153); + this.btnUpload.Location = new System.Drawing.Point(12, 150); this.btnUpload.Name = "btnUpload"; - this.btnUpload.Size = new System.Drawing.Size(93, 23); + this.btnUpload.Size = new System.Drawing.Size(108, 23); this.btnUpload.TabIndex = 5; this.btnUpload.Text = "Upload File"; this.btnUpload.UseVisualStyleBackColor = true; @@ -209,11 +212,11 @@ private void InitializeComponent() // // btnTranslate // - this.btnTranslate.Location = new System.Drawing.Point(113, 153); + this.btnTranslate.Location = new System.Drawing.Point(12, 179); this.btnTranslate.Name = "btnTranslate"; - this.btnTranslate.Size = new System.Drawing.Size(124, 23); + this.btnTranslate.Size = new System.Drawing.Size(108, 23); this.btnTranslate.TabIndex = 6; - this.btnTranslate.Text = "Translate file"; + this.btnTranslate.Text = "Translate File"; this.btnTranslate.UseVisualStyleBackColor = true; this.btnTranslate.Click += new System.EventHandler(this.btnTranslate_Click); // @@ -225,9 +228,9 @@ private void InitializeComponent() // // btnDeleteObject // - this.btnDeleteObject.Location = new System.Drawing.Point(13, 124); + this.btnDeleteObject.Location = new System.Drawing.Point(129, 150); this.btnDeleteObject.Name = "btnDeleteObject"; - this.btnDeleteObject.Size = new System.Drawing.Size(103, 23); + this.btnDeleteObject.Size = new System.Drawing.Size(108, 23); this.btnDeleteObject.TabIndex = 8; this.btnDeleteObject.Text = "Delete Object"; this.btnDeleteObject.UseVisualStyleBackColor = true; @@ -241,13 +244,13 @@ private void InitializeComponent() this.panel1.Location = new System.Drawing.Point(242, 95); this.panel1.Margin = new System.Windows.Forms.Padding(2); this.panel1.Name = "panel1"; - this.panel1.Size = new System.Drawing.Size(446, 477); + this.panel1.Size = new System.Drawing.Size(863, 477); this.panel1.TabIndex = 9; // // btnShowDevTools // this.btnShowDevTools.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnShowDevTools.Location = new System.Drawing.Point(613, 577); + this.btnShowDevTools.Location = new System.Drawing.Point(1030, 577); this.btnShowDevTools.Name = "btnShowDevTools"; this.btnShowDevTools.Size = new System.Drawing.Size(75, 23); this.btnShowDevTools.TabIndex = 10; @@ -258,7 +261,7 @@ private void InitializeComponent() // btnDownloadSVF // this.btnDownloadSVF.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnDownloadSVF.Location = new System.Drawing.Point(492, 577); + this.btnDownloadSVF.Location = new System.Drawing.Point(909, 577); this.btnDownloadSVF.Name = "btnDownloadSVF"; this.btnDownloadSVF.Size = new System.Drawing.Size(115, 23); this.btnDownloadSVF.TabIndex = 11; @@ -269,7 +272,7 @@ private void InitializeComponent() // btnJavaScript // this.btnJavaScript.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.btnJavaScript.Location = new System.Drawing.Point(411, 577); + this.btnJavaScript.Location = new System.Drawing.Point(828, 577); this.btnJavaScript.Name = "btnJavaScript"; this.btnJavaScript.Size = new System.Drawing.Size(75, 23); this.btnJavaScript.TabIndex = 12; @@ -277,6 +280,22 @@ private void InitializeComponent() this.btnJavaScript.UseVisualStyleBackColor = true; this.btnJavaScript.Click += new System.EventHandler(this.btnJavaScript_Click); // + // tbFilter + // + this.tbFilter.Location = new System.Drawing.Point(48, 124); + this.tbFilter.Name = "tbFilter"; + this.tbFilter.Size = new System.Drawing.Size(189, 20); + this.tbFilter.TabIndex = 13; + // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(13, 128); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(29, 13); + this.label3.TabIndex = 14; + this.label3.Text = "Filter"; + // // progressBar // this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) @@ -285,15 +304,28 @@ private void InitializeComponent() this.progressBar.DisplayStyle = bucket.manager.Utils.ProgressBarDisplayText.Percentage; this.progressBar.Location = new System.Drawing.Point(12, 607); this.progressBar.Name = "progressBar"; - this.progressBar.Size = new System.Drawing.Size(676, 23); + this.progressBar.Size = new System.Drawing.Size(1093, 23); this.progressBar.TabIndex = 7; this.progressBar.Visible = false; // + // btnManifest + // + this.btnManifest.Location = new System.Drawing.Point(129, 179); + this.btnManifest.Name = "btnManifest"; + this.btnManifest.Size = new System.Drawing.Size(108, 23); + this.btnManifest.TabIndex = 15; + this.btnManifest.Text = "Show Manifest"; + this.btnManifest.UseVisualStyleBackColor = true; + this.btnManifest.Click += new System.EventHandler(this.btnManifest_Click); + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(700, 642); + this.ClientSize = new System.Drawing.Size(1117, 642); + this.Controls.Add(this.btnManifest); + this.Controls.Add(this.label3); + this.Controls.Add(this.tbFilter); this.Controls.Add(this.btnJavaScript); this.Controls.Add(this.btnDownloadSVF); this.Controls.Add(this.btnShowDevTools); @@ -314,6 +346,7 @@ private void InitializeComponent() this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.ResumeLayout(false); + this.PerformLayout(); } @@ -340,6 +373,9 @@ private void InitializeComponent() private System.Windows.Forms.Button btnShowDevTools; private System.Windows.Forms.Button btnDownloadSVF; private System.Windows.Forms.Button btnJavaScript; + private System.Windows.Forms.TextBox tbFilter; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button btnManifest; } } diff --git a/bucket.manager/Form1.Designer.cs.bak b/bucket.manager/Form1.Designer.cs.bak new file mode 100644 index 0000000..8ac4bcb --- /dev/null +++ b/bucket.manager/Form1.Designer.cs.bak @@ -0,0 +1,345 @@ +///////////////////////////////////////////////////////////////////// +// Copyright (c) Autodesk, Inc. All rights reserved +// Written by Forge Partner Development +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +///////////////////////////////////////////////////////////////////// + +namespace bucket.manager +{ + partial class Form1 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.treeBuckets = new System.Windows.Forms.TreeView(); + this.label1 = new System.Windows.Forms.Label(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.txtTimeout = new System.Windows.Forms.TextBox(); + this.txtAccessToken = new System.Windows.Forms.TextBox(); + this.label4 = new System.Windows.Forms.Label(); + this.btnAuthenticate = new System.Windows.Forms.Button(); + this.txtClientSecret = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.txtClientId = new System.Windows.Forms.TextBox(); + this.btnRefreshToken = new System.Windows.Forms.Button(); + this.btnCreateBucket = new System.Windows.Forms.Button(); + this.btnUpload = new System.Windows.Forms.Button(); + this.btnTranslate = new System.Windows.Forms.Button(); + this.menuTranslate = new System.Windows.Forms.ContextMenuStrip(this.components); + this.btnDeleteObject = new System.Windows.Forms.Button(); + this.panel1 = new System.Windows.Forms.Panel(); + this.btnShowDevTools = new System.Windows.Forms.Button(); + this.btnDownloadSVF = new System.Windows.Forms.Button(); + this.btnJavaScript = new System.Windows.Forms.Button(); + this.progressBar = new bucket.manager.Utils.CustomProgressBar(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // treeBuckets + // + this.treeBuckets.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.treeBuckets.Location = new System.Drawing.Point(12, 182); + this.treeBuckets.Name = "treeBuckets"; + this.treeBuckets.Size = new System.Drawing.Size(225, 419); + this.treeBuckets.TabIndex = 0; + this.treeBuckets.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.treeBuckets_AfterSelect); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(14, 24); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(21, 13); + this.label1.TabIndex = 1; + this.label1.Text = "ID:"; + // + // groupBox1 + // + this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox1.Controls.Add(this.txtTimeout); + this.groupBox1.Controls.Add(this.txtAccessToken); + this.groupBox1.Controls.Add(this.label4); + this.groupBox1.Controls.Add(this.btnAuthenticate); + this.groupBox1.Controls.Add(this.txtClientSecret); + this.groupBox1.Controls.Add(this.label2); + this.groupBox1.Controls.Add(this.txtClientId); + this.groupBox1.Controls.Add(this.label1); + this.groupBox1.Location = new System.Drawing.Point(13, 13); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(675, 76); + this.groupBox1.TabIndex = 2; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "Forge Credentials"; + // + // txtTimeout + // + this.txtTimeout.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.txtTimeout.Location = new System.Drawing.Point(583, 46); + this.txtTimeout.Name = "txtTimeout"; + this.txtTimeout.ReadOnly = true; + this.txtTimeout.Size = new System.Drawing.Size(86, 20); + this.txtTimeout.TabIndex = 10; + this.txtTimeout.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; + // + // txtAccessToken + // + this.txtAccessToken.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtAccessToken.Location = new System.Drawing.Point(100, 46); + this.txtAccessToken.Name = "txtAccessToken"; + this.txtAccessToken.ReadOnly = true; + this.txtAccessToken.Size = new System.Drawing.Size(477, 20); + this.txtAccessToken.TabIndex = 9; + // + // label4 + // + this.label4.AutoSize = true; + this.label4.Location = new System.Drawing.Point(14, 49); + this.label4.Name = "label4"; + this.label4.Size = new System.Drawing.Size(79, 13); + this.label4.TabIndex = 8; + this.label4.Text = "Access Token:"; + // + // btnAuthenticate + // + this.btnAuthenticate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.btnAuthenticate.Location = new System.Drawing.Point(583, 18); + this.btnAuthenticate.Name = "btnAuthenticate"; + this.btnAuthenticate.Size = new System.Drawing.Size(86, 23); + this.btnAuthenticate.TabIndex = 5; + this.btnAuthenticate.Text = "Authenticate"; + this.btnAuthenticate.UseVisualStyleBackColor = true; + this.btnAuthenticate.Click += new System.EventHandler(this.btnAuthenticate_Click); + // + // txtClientSecret + // + this.txtClientSecret.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.txtClientSecret.Location = new System.Drawing.Point(384, 20); + this.txtClientSecret.Name = "txtClientSecret"; + this.txtClientSecret.PasswordChar = '*'; + this.txtClientSecret.Size = new System.Drawing.Size(193, 20); + this.txtClientSecret.TabIndex = 4; + // + // label2 + // + this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(337, 24); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(41, 13); + this.label2.TabIndex = 3; + this.label2.Text = "Secret:"; + // + // txtClientId + // + this.txtClientId.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.txtClientId.Location = new System.Drawing.Point(35, 20); + this.txtClientId.Name = "txtClientId"; + this.txtClientId.Size = new System.Drawing.Size(296, 20); + this.txtClientId.TabIndex = 2; + // + // btnRefreshToken + // + this.btnRefreshToken.Location = new System.Drawing.Point(13, 95); + this.btnRefreshToken.Name = "btnRefreshToken"; + this.btnRefreshToken.Size = new System.Drawing.Size(121, 23); + this.btnRefreshToken.TabIndex = 3; + this.btnRefreshToken.Text = "Refresh buckets"; + this.btnRefreshToken.UseVisualStyleBackColor = true; + this.btnRefreshToken.Click += new System.EventHandler(this.btnRefreshToken_Click); + // + // btnCreateBucket + // + this.btnCreateBucket.Location = new System.Drawing.Point(140, 95); + this.btnCreateBucket.Name = "btnCreateBucket"; + this.btnCreateBucket.Size = new System.Drawing.Size(97, 23); + this.btnCreateBucket.TabIndex = 4; + this.btnCreateBucket.Text = "Create Bucket"; + this.btnCreateBucket.UseVisualStyleBackColor = true; + this.btnCreateBucket.Click += new System.EventHandler(this.btnCreateBucket_Click); + // + // btnUpload + // + this.btnUpload.Location = new System.Drawing.Point(13, 153); + this.btnUpload.Name = "btnUpload"; + this.btnUpload.Size = new System.Drawing.Size(93, 23); + this.btnUpload.TabIndex = 5; + this.btnUpload.Text = "Upload File"; + this.btnUpload.UseVisualStyleBackColor = true; + this.btnUpload.Click += new System.EventHandler(this.btnUpload_Click); + // + // btnTranslate + // + this.btnTranslate.Location = new System.Drawing.Point(113, 153); + this.btnTranslate.Name = "btnTranslate"; + this.btnTranslate.Size = new System.Drawing.Size(124, 23); + this.btnTranslate.TabIndex = 6; + this.btnTranslate.Text = "Translate file"; + this.btnTranslate.UseVisualStyleBackColor = true; + this.btnTranslate.Click += new System.EventHandler(this.btnTranslate_Click); + // + // menuTranslate + // + this.menuTranslate.ImageScalingSize = new System.Drawing.Size(20, 20); + this.menuTranslate.Name = "menuTranslate"; + this.menuTranslate.Size = new System.Drawing.Size(61, 4); + // + // btnDeleteObject + // + this.btnDeleteObject.Location = new System.Drawing.Point(13, 124); + this.btnDeleteObject.Name = "btnDeleteObject"; + this.btnDeleteObject.Size = new System.Drawing.Size(103, 23); + this.btnDeleteObject.TabIndex = 8; + this.btnDeleteObject.Text = "Delete Object"; + this.btnDeleteObject.UseVisualStyleBackColor = true; + this.btnDeleteObject.Click += new System.EventHandler(this.btnDeleteObject_Click); + // + // panel1 + // + this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.panel1.Location = new System.Drawing.Point(242, 95); + this.panel1.Margin = new System.Windows.Forms.Padding(2); + this.panel1.Name = "panel1"; + this.panel1.Size = new System.Drawing.Size(446, 477); + this.panel1.TabIndex = 9; + // + // btnShowDevTools + // + this.btnShowDevTools.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnShowDevTools.Location = new System.Drawing.Point(613, 577); + this.btnShowDevTools.Name = "btnShowDevTools"; + this.btnShowDevTools.Size = new System.Drawing.Size(75, 23); + this.btnShowDevTools.TabIndex = 10; + this.btnShowDevTools.Text = "DevTools"; + this.btnShowDevTools.UseVisualStyleBackColor = true; + this.btnShowDevTools.Click += new System.EventHandler(this.btnShowDevTools_Click); + // + // btnDownloadSVF + // + this.btnDownloadSVF.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnDownloadSVF.Location = new System.Drawing.Point(492, 577); + this.btnDownloadSVF.Name = "btnDownloadSVF"; + this.btnDownloadSVF.Size = new System.Drawing.Size(115, 23); + this.btnDownloadSVF.TabIndex = 11; + this.btnDownloadSVF.Text = "Download SVF"; + this.btnDownloadSVF.UseVisualStyleBackColor = true; + this.btnDownloadSVF.Click += new System.EventHandler(this.btnDownloadSVF_Click); + // + // btnJavaScript + // + this.btnJavaScript.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btnJavaScript.Location = new System.Drawing.Point(411, 577); + this.btnJavaScript.Name = "btnJavaScript"; + this.btnJavaScript.Size = new System.Drawing.Size(75, 23); + this.btnJavaScript.TabIndex = 12; + this.btnJavaScript.Text = "JavaScript"; + this.btnJavaScript.UseVisualStyleBackColor = true; + this.btnJavaScript.Click += new System.EventHandler(this.btnJavaScript_Click); + // + // progressBar + // + this.progressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.progressBar.CustomText = null; + this.progressBar.DisplayStyle = bucket.manager.Utils.ProgressBarDisplayText.Percentage; + this.progressBar.Location = new System.Drawing.Point(12, 607); + this.progressBar.Name = "progressBar"; + this.progressBar.Size = new System.Drawing.Size(676, 23); + this.progressBar.TabIndex = 7; + this.progressBar.Visible = false; + // + // Form1 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(700, 642); + this.Controls.Add(this.btnJavaScript); + this.Controls.Add(this.btnDownloadSVF); + this.Controls.Add(this.btnShowDevTools); + this.Controls.Add(this.panel1); + this.Controls.Add(this.btnDeleteObject); + this.Controls.Add(this.progressBar); + this.Controls.Add(this.btnTranslate); + this.Controls.Add(this.btnUpload); + this.Controls.Add(this.btnCreateBucket); + this.Controls.Add(this.btnRefreshToken); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.treeBuckets); + this.Name = "Form1"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "Bucket Manager"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); + this.Load += new System.EventHandler(this.Form1_Load); + this.groupBox1.ResumeLayout(false); + this.groupBox1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TreeView treeBuckets; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.TextBox txtAccessToken; + private System.Windows.Forms.Label label4; + private System.Windows.Forms.Button btnAuthenticate; + private System.Windows.Forms.TextBox txtClientSecret; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.TextBox txtClientId; + private System.Windows.Forms.TextBox txtTimeout; + private System.Windows.Forms.Button btnRefreshToken; + private System.Windows.Forms.Button btnCreateBucket; + private System.Windows.Forms.Button btnUpload; + private System.Windows.Forms.Button btnTranslate; + private Utils.CustomProgressBar progressBar; + private System.Windows.Forms.ContextMenuStrip menuTranslate; + private System.Windows.Forms.Button btnDeleteObject; + private System.Windows.Forms.Panel panel1; + private System.Windows.Forms.Button btnShowDevTools; + private System.Windows.Forms.Button btnDownloadSVF; + private System.Windows.Forms.Button btnJavaScript; + } +} + diff --git a/bucket.manager/Form1.cs b/bucket.manager/Form1.cs index e0364b5..1b3d435 100644 --- a/bucket.manager/Form1.cs +++ b/bucket.manager/Form1.cs @@ -131,23 +131,51 @@ private async void btnRefreshToken_Click(object sender, EventArgs e) foreach (TreeNode n in treeBuckets.Nodes) if (n != null) // async? await ShowBucketObjects(n); + + treeBuckets.Sort(); } private async Task ShowBucketObjects(TreeNode nodeBucket) { + string filter = tbFilter.Text; + if (filter == "") filter = null; + nodeBucket.Nodes.Clear(); + // control GetBucket pagination + string lastNode = null; + int itemCount = 0; + ObjectsApi objects = new ObjectsApi(); objects.Configuration.AccessToken = AccessToken; // show objects on the given TreeNode - var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag); - foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) + do { - TreeNode nodeObject = new TreeNode(objInfo.Value.objectKey); - nodeObject.Tag = ((string)objInfo.Value.objectId).Base64Encode(); - nodeBucket.Nodes.Add(nodeObject); - } + var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag, 100, filter, lastNode); //"24288A-1000" + itemCount += objectsList.items.Count; + if (itemCount == 0) break; + if (((DynamicJsonResponse)objectsList).Dictionary.ContainsKey("next") && objectsList.next != null) + { + lastNode = ((string)objectsList.next); + int start = lastNode.IndexOf("startAt=") + 8; + int end = lastNode.IndexOf("&limit="); + lastNode = Uri.UnescapeDataString(lastNode.Substring(start, end - start)); + } + else + { + lastNode = null; + } + + foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) + { + TreeNode nodeObject = new TreeNode(objInfo.Value.objectKey); + nodeObject.Tag = ((string)objInfo.Value.objectId).Base64Encode(); + nodeBucket.Nodes.Add(nodeObject); + + } + if (lastNode == null) break; + } while ((itemCount % 100) == 0); } private const int UPLOAD_CHUNK_SIZE = 2; // Mb @@ -177,8 +205,8 @@ private async void btnUpload_Click(object sender, EventArgs e) // show progress bar for upload progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; progressBar.Show(); - progressBar.Value = 0; progressBar.Minimum = 0; + progressBar.Value = 0; progressBar.CustomText = "Preparing to upload file..."; // decide if upload direct or resumable (by chunks) @@ -224,8 +252,8 @@ private async void btnUpload_Click(object sender, EventArgs e) { using (StreamReader streamReader = new StreamReader(filePath)) { - progressBar.Value = 50; // random... progressBar.Maximum = 100; + progressBar.Value = 50; // random... dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, "application/octet-stream"); @@ -253,6 +281,32 @@ private void btnTranslate_Click(object sender, EventArgs e) menuTranslate.Show(btnTranslate, new Point(0, btnTranslate.Height)); } + private void btnManifest_Click(object sender, EventArgs e) + { + // check level 1 of objects + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string urn = (string)treeBuckets.SelectedNode.Tag; + + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = AccessToken; + try + { + string aManifest = derivative.GetManifest(urn).ToString(); + + using (var displayText = new DisplayText(aManifest)) + { + displayText.ShowDialog(); + } + } catch (Exception ex) + { + MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + private async void onClickTranslate(object sender, EventArgs e) { // for now, just one translation at a time @@ -285,9 +339,9 @@ private async void onClickTranslate(object sender, EventArgs e) // start progress bar for translation progressBar.Show(); - progressBar.Value = 0; progressBar.Minimum = 0; progressBar.Maximum = 100; + progressBar.Value = 0; progressBar.CustomText = "Starting translation job..."; // start translation job diff --git a/bucket.manager/Form1.cs.bak b/bucket.manager/Form1.cs.bak new file mode 100644 index 0000000..d4c338a --- /dev/null +++ b/bucket.manager/Form1.cs.bak @@ -0,0 +1,455 @@ +///////////////////////////////////////////////////////////////////// +// Copyright (c) Autodesk, Inc. All rights reserved +// Written by Forge Partner Development +// +// Permission to use, copy, modify, and distribute this software in +// object code form for any purpose and without fee is hereby granted, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and the limited warranty and +// restricted rights notice below appear in all supporting +// documentation. +// +// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. +// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF +// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. +// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE +// UNINTERRUPTED OR ERROR FREE. +///////////////////////////////////////////////////////////////////// + +using Autodesk.Forge; +using Autodesk.Forge.Model; +using bucket.manager.Utils; +using CefSharp; +using CefSharp.WinForms; +using RestSharp; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace bucket.manager +{ + public partial class Form1 : Form + { + public Form1() + { + InitializeComponent(); + InitBrowser(); + } + + public ChromiumWebBrowser browser; + + public void InitBrowser() + { + Cef.Initialize(new CefSettings()); + browser = new ChromiumWebBrowser("file:///HTML/Viewer.html"); // CefSharp needs a initial page... + + browser.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + browser.MinimumSize = new System.Drawing.Size(20, 20); + browser.Name = "webBrowser1"; + browser.TabIndex = 1; + browser.Dock = DockStyle.Fill; + panel1.Controls.Add(browser); + } + + private Timer _tokenTimer = new Timer(); + private Timer _translationTimer = new Timer(); + private DateTime _expiresAt; + + private async void btnAuthenticate_Click(object sender, EventArgs e) + { + if (string.IsNullOrWhiteSpace(txtClientId.Text) || string.IsNullOrWhiteSpace(txtClientSecret.Text)) return; + + // get the access token + TwoLeggedApi oAuth = new TwoLeggedApi(); + dynamic token = await oAuth.AuthenticateAsync( + txtClientId.Text, + txtClientSecret.Text, + oAuthConstants.CLIENT_CREDENTIALS, + new Scope[] { Scope.BucketRead, Scope.BucketCreate, Scope.DataRead, Scope.DataWrite }); + txtAccessToken.Text = token.access_token; + _expiresAt = DateTime.Now.AddSeconds(token.expires_in); + + // keep track on time + _tokenTimer.Tick += new EventHandler(tickTokenTimer); + _tokenTimer.Interval = 1000; + _tokenTimer.Enabled = true; + + btnRefreshToken_Click(null, null); + } + + void tickTokenTimer(object sender, EventArgs e) + { + // update the time left on the access token + double secondsLeft = (_expiresAt - DateTime.Now).TotalSeconds; + txtTimeout.Text = secondsLeft.ToString("0"); + txtTimeout.BackColor = (secondsLeft < 60 ? System.Drawing.Color.Red : System.Drawing.SystemColors.Control); + } + + private string AccessToken + { + get + { + return txtAccessToken.Text; + } + } + + private async void btnRefreshToken_Click(object sender, EventArgs e) + { + treeBuckets.Nodes.Clear(); + + BucketsApi bucketApi = new BucketsApi(); + bucketApi.Configuration.AccessToken = AccessToken; + + // control GetBucket pagination + string lastBucket = null; + int itemCount = 0; + + // get buckets until returned list length < 100 + do + { + dynamic buckets = await bucketApi.GetBucketsAsync(null, 100, lastBucket); + itemCount += buckets.items.Count; + + foreach (KeyValuePair bucket in new DynamicDictionaryItems(buckets.items)) + { + TreeNode nodeBucket = new TreeNode(bucket.Value.bucketKey); + nodeBucket.Tag = bucket.Value.bucketKey; + treeBuckets.Nodes.Add(nodeBucket); + + lastBucket = bucket.Value.bucketKey; // after the loop, this will contain the last bucketKey + } + } while ((itemCount % 100) == 0); // while GetBuckets returns 100, we need to get next page + + // for each bucket, show the objects + foreach (TreeNode n in treeBuckets.Nodes) + if (n != null) // async? + await ShowBucketObjects(n); + } + + private async Task ShowBucketObjects(TreeNode nodeBucket) + { + nodeBucket.Nodes.Clear(); + + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + + // show objects on the given TreeNode + var objectsList = await objects.GetObjectsAsync((string)nodeBucket.Tag); + foreach (KeyValuePair objInfo in new DynamicDictionaryItems(objectsList.items)) + { + TreeNode nodeObject = new TreeNode(objInfo.Value.objectKey); + nodeObject.Tag = ((string)objInfo.Value.objectId).Base64Encode(); + nodeBucket.Nodes.Add(nodeObject); + } + } + + private const int UPLOAD_CHUNK_SIZE = 2; // Mb + + private async void btnUpload_Click(object sender, EventArgs e) + { + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 0) + { + MessageBox.Show("Please select a bucket", "Bucket required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string bucketKey = treeBuckets.SelectedNode.Text; + + // ask user to select file + OpenFileDialog formSelectFile = new OpenFileDialog(); + formSelectFile.Multiselect = false; + if (formSelectFile.ShowDialog() != DialogResult.OK) return; + string filePath = formSelectFile.FileName; + string objectKey = Path.GetFileName(filePath); + + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + + // get file size + long fileSize = (new FileInfo(filePath)).Length; + + // show progress bar for upload + progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; + progressBar.Show(); + progressBar.Value = 0; + progressBar.Minimum = 0; + progressBar.CustomText = "Preparing to upload file..."; + + // decide if upload direct or resumable (by chunks) + if (fileSize > UPLOAD_CHUNK_SIZE * 1024 * 1024) // upload in chunks + { + long chunkSize = 2 * 1024 * 1024; // 2 Mb + long numberOfChunks = (long)Math.Round((double)(fileSize / chunkSize)) + 1; + + progressBar.Maximum = (int)numberOfChunks; + + long start = 0; + chunkSize = (numberOfChunks > 1 ? chunkSize : fileSize); + long end = chunkSize; + string sessionId = Guid.NewGuid().ToString(); + + // upload one chunk at a time + using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open))) + { + for (int chunkIndex = 0; chunkIndex < numberOfChunks; chunkIndex++) + { + string range = string.Format("bytes {0}-{1}/{2}", start, end, fileSize); + + long numberOfBytes = chunkSize + 1; + byte[] fileBytes = new byte[numberOfBytes]; + MemoryStream memoryStream = new MemoryStream(fileBytes); + reader.BaseStream.Seek((int)start, SeekOrigin.Begin); + int count = reader.Read(fileBytes, 0, (int)numberOfBytes); + memoryStream.Write(fileBytes, 0, (int)numberOfBytes); + memoryStream.Position = 0; + + dynamic chunkUploadResponse = await objects.UploadChunkAsync(bucketKey, objectKey, (int)numberOfBytes, range, sessionId, memoryStream); + + start = end + 1; + chunkSize = ((start + chunkSize > fileSize) ? fileSize - start - 1 : chunkSize); + end = start + chunkSize; + + progressBar.CustomText = string.Format("{0} Mb uploaded...", (chunkIndex * chunkSize) / 1024 / 1024); + progressBar.Value = chunkIndex; + } + } + } + else // upload in a single call + { + using (StreamReader streamReader = new StreamReader(filePath)) + { + progressBar.Value = 50; // random... + progressBar.Maximum = 100; + dynamic uploadedObj = await objects.UploadObjectAsync(bucketKey, + objectKey, (int)streamReader.BaseStream.Length, streamReader.BaseStream, + "application/octet-stream"); + } + + } + + progressBar.Hide(); + await ShowBucketObjects(treeBuckets.SelectedNode); + treeBuckets.SelectedNode.Expand(); + } + + private void Form1_Load(object sender, EventArgs e) + { + // authenticate when starts + btnAuthenticate_Click(null, null); + } + + private void btnTranslate_Click(object sender, EventArgs e) + { + // show menu with translation options + // ToDo: include other translation formats + menuTranslate.Items.Clear(); + menuTranslate.Items.Add("Viewer (SVF)", null, onClickTranslate); + menuTranslate.Show(btnTranslate, new Point(0, btnTranslate.Height)); + } + + private async void onClickTranslate(object sender, EventArgs e) + { + // for now, just one translation at a time + if (_translationTimer.Enabled) return; + + // check level 1 of objects + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string urn = (string)treeBuckets.SelectedNode.Tag; + + // prepare a SVF translation + List outputs = new List() + { + new JobPayloadItem( + JobPayloadItem.TypeEnum.Svf, + new List() + { + JobPayloadItem.ViewsEnum._2d, + JobPayloadItem.ViewsEnum._3d + }) + }; + JobPayload job; + //if (string.IsNullOrEmpty(objModel.rootFilename)) + job = new JobPayload(new JobPayloadInput(urn), new JobPayloadOutput(outputs)); + //else + // job = new JobPayload(new JobPayloadInput(objModel.objectKey, true, objModel.rootFilename), new JobPayloadOutput(outputs)); + + // start progress bar for translation + progressBar.Show(); + progressBar.Value = 0; + progressBar.Minimum = 0; + progressBar.Maximum = 100; + progressBar.CustomText = "Starting translation job..."; + + // start translation job + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = AccessToken; + dynamic jobPosted = await derivative.TranslateAsync(job, true); + + // start a monitor job to follow the translation + _translationTimer.Tick += new EventHandler(isTranslationReady); + _translationTimer.Tag = urn; + _translationTimer.Interval = 5000; + _translationTimer.Enabled = true; + } + + private async void isTranslationReady(object sender, EventArgs e) + { + DerivativesApi derivative = new DerivativesApi(); + derivative.Configuration.AccessToken = AccessToken; + + // get the translation manifest + dynamic manifest = await derivative.GetManifestAsync((string)_translationTimer.Tag); + int progress = (string.IsNullOrWhiteSpace(Regex.Match(manifest.progress, @"\d+").Value) ? 100 : Int32.Parse(Regex.Match(manifest.progress, @"\d+").Value)); + + // for better UX, show a small number of progress (instead zero) + progressBar.Value = (progress == 0 ? 10 : progress); + progressBar.CustomText = string.Format("Translation in progress: {0}", progress); + Debug.WriteLine(progress); + + // if ready, hide everything + if (progress >= 100) + { + progressBar.Hide(); + _translationTimer.Enabled = false; + } + } + + private async void btnDeleteObject_Click(object sender, EventArgs e) + { + // treeBuckets level 1 are for Objects + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + if (MessageBox.Show("This objects will be permantly delete, confirm?", "Are you sure?", + MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + return; + + // call API to delete object on the bucket + ObjectsApi objects = new ObjectsApi(); + objects.Configuration.AccessToken = AccessToken; + await objects.DeleteObjectAsync((string)treeBuckets.SelectedNode.Parent.Tag, (string)treeBuckets.SelectedNode.Text); + await ShowBucketObjects(treeBuckets.SelectedNode.Parent); + } + + private void Form1_FormClosing(object sender, FormClosingEventArgs e) + { + // required by CefSharp Browser + Cef.Shutdown(); + } + + private void treeBuckets_AfterSelect(object sender, TreeViewEventArgs e) + { + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) return; + + // this basic HTML page to show the model passing URN & Access Token + browser.Load(string.Format("file:///HTML/Viewer.html?URN={0}&Token={1}", treeBuckets.SelectedNode.Tag, AccessToken)); + } + + private async void btnCreateBucket_Click(object sender, EventArgs e) + { + string bucketKey = string.Empty; + if (Prompt.ShowDialog("Enter bucket name: ", "Create new bucket", txtClientId.Text.ToLower() + DateTime.Now.Ticks.ToString(), out bucketKey) == DialogResult.OK) + { + BucketsApi buckets = new BucketsApi(); + buckets.Configuration.AccessToken = AccessToken; + PostBucketsPayload bucketPayload = new PostBucketsPayload(bucketKey.ToLower(), null, PostBucketsPayload.PolicyKeyEnum.Transient); + await buckets.CreateBucketAsync(bucketPayload); + + btnRefreshToken_Click(null, null); + } + } + + private void btnShowDevTools_Click(object sender, EventArgs e) + { + browser.ShowDevTools(); + } + + private async void btnDownloadSVF_Click(object sender, EventArgs e) + { + // ensure the selected node is an object and get its URN + if (treeBuckets.SelectedNode == null || treeBuckets.SelectedNode.Level != 1) + { + MessageBox.Show("Please select an object", "Objects required", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + string urn = (string)treeBuckets.SelectedNode.Tag; + + // select a folder to download the files + string folderPath = string.Empty; + using (var fbd = new FolderBrowserDialog()) + { + if (fbd.ShowDialog() != DialogResult.OK || string.IsNullOrWhiteSpace(fbd.SelectedPath)) return; + folderPath = fbd.SelectedPath; + folderPath = Path.Combine(folderPath, treeBuckets.SelectedNode.Text); + if (Directory.Exists(folderPath)) Directory.Delete(folderPath, true); + Directory.CreateDirectory(folderPath); + } + + // prepare the UI + progressBar.Show(); + progressBar.DisplayStyle = ProgressBarDisplayText.CustomText; + progressBar.Value = 0; + progressBar.CustomText = "Starting extraction..."; + + // get the list of resources to download + List resourcesToDownload = await ForgeUtils.Derivatives.ExtractSVFAsync(urn, AccessToken); + + // update the UI + progressBar.Minimum = 0; + progressBar.Maximum = resourcesToDownload.Count; + progressBar.Step = 1; + + IRestClient client = new RestClient("https://developer.api.autodesk.com/"); + foreach (ForgeUtils.Derivatives.Resource resource in resourcesToDownload) + { + progressBar.PerformStep(); + progressBar.CustomText = "Downloading " + resource.FileName; + + // prepare the GET to download the file + RestRequest request = new RestRequest(resource.RemotePath, Method.GET); + request.AddHeader("Authorization", "Bearer " + AccessToken); + request.AddHeader("Accept-Encoding", "gzip, deflate"); + IRestResponse response = await client.ExecuteTaskAsync(request); + + if (response.StatusCode != System.Net.HttpStatusCode.OK) + { + // something went wrong with this file... + MessageBox.Show(string.Format("Error downloading {0}: {1}", + resource.FileName, response.StatusCode.ToString())); + + // any other action? + } + else + { + // combine with selected local path + string pathToSave = Path.Combine(folderPath, resource.LocalPath); + // ensure local dir exists + Directory.CreateDirectory(Path.GetDirectoryName(pathToSave)); + // save file + File.WriteAllBytes(pathToSave, response.RawBytes); + } + } + + progressBar.Hide(); + } + + private void btnJavaScript_Click(object sender, EventArgs e) + { + Tools.JSEditor editor = new Tools.JSEditor(this.browser); + editor.Show(); + } + } +} diff --git a/bucket.manager/Utils/CustomProgress.cs b/bucket.manager/Utils/CustomProgress.cs index c1702c3..36afdb3 100644 --- a/bucket.manager/Utils/CustomProgress.cs +++ b/bucket.manager/Utils/CustomProgress.cs @@ -12,7 +12,7 @@ public enum ProgressBarDisplayText CustomText } - class CustomProgressBar : ProgressBar + public class CustomProgressBar : ProgressBar { //Property to set to decide whether to print a % or Text public ProgressBarDisplayText DisplayStyle { get; set; } diff --git a/bucket.manager/Utils/CustomProgress.cs.bak b/bucket.manager/Utils/CustomProgress.cs.bak new file mode 100644 index 0000000..ac2aad7 --- /dev/null +++ b/bucket.manager/Utils/CustomProgress.cs.bak @@ -0,0 +1,61 @@ +// From https://stackoverflow.com/a/3529945 + +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace bucket.manager.Utils +{ + public enum ProgressBarDisplayText + { + Percentage, + CustomText + } + + class CustomProgressBar : ProgressBar + { + //Property to set to decide whether to print a % or Text + public ProgressBarDisplayText DisplayStyle { get; set; } + + //Property to hold the custom text + public String CustomText { get; set; } + + public CustomProgressBar() + { + // Modify the ControlStyles flags + //http://msdn.microsoft.com/en-us/library/system.windows.forms.controlstyles.aspx + SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true); + } + + protected override void OnPaint(PaintEventArgs e) + { + Rectangle rect = ClientRectangle; + Graphics g = e.Graphics; + + ProgressBarRenderer.DrawHorizontalBar(g, rect); + rect.Inflate(-3, -3); + if (Value > 0) + { + // As we doing this ourselves we need to draw the chunks on the progress bar + Rectangle clip = new Rectangle(rect.X, rect.Y, (int)Math.Round(((float)Value / Maximum) * rect.Width), rect.Height); + ProgressBarRenderer.DrawHorizontalChunks(g, clip); + } + + // Set the Display text (Either a % amount or our custom text + string text = DisplayStyle == ProgressBarDisplayText.Percentage ? Value.ToString() + '%' : CustomText; + + + using (Font f = new Font(FontFamily.GenericSerif, 10)) + { + + SizeF len = g.MeasureString(text, f); + // Calculate the location of the text (the middle of progress bar) + // Point location = new Point(Convert.ToInt32((rect.Width / 2) - (len.Width / 2)), Convert.ToInt32((rect.Height / 2) - (len.Height / 2))); + Point location = new Point(Convert.ToInt32((Width / 2) - len.Width / 2), Convert.ToInt32((Height / 2) - len.Height / 2)); + // The commented-out code will centre the text into the highlighted area only. This will centre the text regardless of the highlighted area. + // Draw the custom text + g.DrawString(text, f, Brushes.Red, location); + } + } + } +} diff --git a/bucket.manager/bucket.manager.csproj b/bucket.manager/bucket.manager.csproj index 83b0603..aff624f 100644 --- a/bucket.manager/bucket.manager.csproj +++ b/bucket.manager/bucket.manager.csproj @@ -104,6 +104,12 @@ + + Form + + + DisplayText.cs + Form @@ -124,6 +130,9 @@ Component + + DisplayText.cs + Form1.cs diff --git a/bucket.manager/bucket.manager.csproj.bak b/bucket.manager/bucket.manager.csproj.bak new file mode 100644 index 0000000..14696db --- /dev/null +++ b/bucket.manager/bucket.manager.csproj.bak @@ -0,0 +1,180 @@ + + + + + + + Debug + AnyCPU + {09A7D975-D2F9-4FF4-8536-815DCF98CA97} + WinExe + bucket.manager + bucket.manager + v4.6 + 512 + true + + + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + true + + + + packages\Autodesk.Forge.1.4.0\lib\net452\Autodesk.Forge.dll + + + packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + + + packages\RestSharp.106.3.1\lib\net452\RestSharp.dll + + + packages\jacobslusser.ScintillaNET.3.6.3\lib\net40\ScintillaNET.dll + + + + + + + + + + + + + + + + + + + Form + + + Form1.cs + + + Form + + + JSEditor.cs + + + + + + + Component + + + Form1.cs + + + JSEditor.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + Designer + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + Always + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + + + \ No newline at end of file