Created
April 27, 2020 21:53
-
-
Save facebookegypt/6ed1bef18dfac7a73939d39d381f1550 to your computer and use it in GitHub Desktop.
Visual Basic .Net Dropbox Api Class using [Access Token] Flow method to Auth. , upload and download files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'Open Project->Settings->Add user scope [accesstoken | User] , [uid | user]. | |
'Create VB Class [DropboxC.vb] in your Visual Basic project, place this code in it. | |
Imports System.IO | |
Imports System.Net | |
Imports System.Net.Http | |
Imports System.Runtime.InteropServices | |
Imports Dropbox.Api | |
Imports Dropbox.Api.Common | |
Imports Dropbox.Api.Files | |
Imports Dropbox.Api.Files.Routes | |
Imports Dropbox.Api.Team | |
Public Class DropBoxC | |
' Add an AppKey (from https//www.dropbox.com/developers/apps) here | |
Private Const ApiKey As String = "YOUR_APP_KEY" | |
' This loopback host Is for demo purpose. If this port Is Not | |
' available on your machine you need to update this URL with an unused port. | |
Private Const LoopBackHost As String = "http://127.0.0.1:52475/" | |
' URL to receive OAuth 2 redirect from Dropbox server. | |
' You also need to register this redirect URL on https://www.dropbox.com/developers/apps. | |
Private ReadOnly RedirectUri As Uri = New Uri(LoopBackHost + "authorize") | |
' URL to receive access token from JS. | |
Private ReadOnly JSRedirectUri As Uri = New Uri(LoopBackHost + "token") | |
<DllImport("kernel32.dll", ExactSpelling:=True)> | |
Private Shared Function GetConsoleWindow() As IntPtr | |
End Function | |
<DllImport("user32.dll")> | |
Private Shared Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean | |
End Function | |
Public Async Function Run() As Task(Of Integer) | |
DropboxCertHelper.InitializeCertPinning() | |
Dim accessToken = Await GetAccessToken() | |
If String.IsNullOrEmpty(accessToken) Then | |
Return 1 | |
End If | |
' Specify socket level timeout which decides maximum waiting time when no bytes are | |
' received by the socket. | |
Dim httpClient = New HttpClient(New WebRequestHandler() With {.ReadWriteTimeout = 10 * 1000}) | |
Try | |
'Your_Project_Name -> to be replaced by your own project name. | |
Dim config = New DropboxClientConfig("YOUR_Project_Name") | |
Dim client = New DropboxClient(accessToken, config) | |
Await RunUserTests(client) | |
' Tests below are for Dropbox Business endpoints. To run these tests, make sure the ApiKey is for | |
' a Dropbox Business app and you have an admin account to log in. | |
Catch e As HttpException | |
System.Diagnostics.Debug.WriteLine("Exception reported from RPC layer") | |
System.Diagnostics.Debug.WriteLine(" Status code: {0}", e.StatusCode) | |
System.Diagnostics.Debug.WriteLine(" Message : {0}", e.Message) | |
If (Not (e.RequestUri) Is Nothing) Then | |
System.Diagnostics.Debug.WriteLine(" Request uri: {0}", e.RequestUri) | |
End If | |
End Try | |
Return 0 | |
End Function | |
''' <summary> | |
''' Gets information about the currently authorized account. | |
''' <para> | |
''' This demonstrates calling a simple rpc style api from the Users namespace. | |
''' </para> | |
''' </summary> | |
''' <param name="client">The Dropbox client.</param> | |
''' <returns>An asynchronous task.</returns> | |
Private Async Function GetCurrentAccount(ByVal client As DropboxClient) As Task | |
Dim full = Await client.Users.GetCurrentAccountAsync | |
System.Diagnostics.Debug.WriteLine("Account id : {0}", full.AccountId) | |
System.Diagnostics.Debug.WriteLine("Country : {0}", full.Country) | |
System.Diagnostics.Debug.WriteLine("Email : {0}", full.Email) | |
System.Diagnostics.Debug.WriteLine("Is paired : {0}", "Yes") | |
'TODO: Warning!!!, inline IF is not supported ? | |
'full.IsPaired | |
System.Diagnostics.Debug.WriteLine("Locale : {0}", full.Locale) | |
System.Diagnostics.Debug.WriteLine("Name") | |
System.Diagnostics.Debug.WriteLine(" Display : {0}", full.Name.DisplayName) | |
System.Diagnostics.Debug.WriteLine(" Familiar : {0}", full.Name.FamiliarName) | |
System.Diagnostics.Debug.WriteLine(" Given : {0}", full.Name.GivenName) | |
System.Diagnostics.Debug.WriteLine(" Surname : {0}", full.Name.Surname) | |
System.Diagnostics.Debug.WriteLine("Referral link : {0}", full.ReferralLink) | |
If (Not (full.Team) Is Nothing) Then | |
System.Diagnostics.Debug.WriteLine("Team") | |
System.Diagnostics.Debug.WriteLine(" Id : {0}", full.Team.Id) | |
System.Diagnostics.Debug.WriteLine(" Name : {0}", full.Team.Name) | |
Else | |
System.Diagnostics.Debug.WriteLine("Team - None") | |
End If | |
End Function | |
''' <summary> | |
''' Creates the specified folder. | |
''' </summary> | |
''' <remarks>This demonstrates calling an rpc style api in the Files namespace.</remarks> | |
''' <param name="path">The path of the folder to create.</param> | |
''' <param name="client">The Dropbox client.</param> | |
''' <returns>The result from the ListFolderAsync call.</returns> | |
Private Async Function CreateFolder(ByVal client As DropboxClient, ByVal path As String) As Task(Of FolderMetadata) | |
System.Diagnostics.Debug.WriteLine("--- Creating Folder ---") | |
Dim folderArg = New CreateFolderArg(path, True) | |
Dim folder = Await client.Files.CreateFolderV2Async(folderArg) | |
System.Diagnostics.Debug.WriteLine(("Folder: " _ | |
+ (path + " created!"))) | |
Return folder.Metadata | |
End Function | |
Public Async Function FolderExists(Client As DropboxClient, Optional Path As String = ("/Apps")) As Task(Of Boolean) | |
'If your folder is in /Apps folder. | |
System.Diagnostics.Debug.WriteLine("--- Checking Folder ---") | |
Dim list = Await Client.Files.ListFolderAsync(Path) | |
' show folders then files | |
For Each item In list.Entries | |
'Working_Folder -> Folder name to check. | |
If item.IsFolder And item.Name = ("Working_Folder") Then | |
MsgBox("Folder Exists. ->" & item.PathLower) | |
Return True | |
Exit For | |
End If | |
Next | |
Return False | |
End Function | |
''' <summary> | |
''' Lists the items within a folder. | |
''' </summary> | |
''' <remarks>This demonstrates calling an rpc style api in the Files namespace.</remarks> | |
''' <param name="path">The path to list.</param> | |
''' <param name="client">The Dropbox client.</param> | |
''' <returns>The result from the ListFolderAsync call.</returns> | |
Private Async Function ListFolder(ByVal client As DropboxClient, ByVal path As String) As Task(Of ListFolderResult) | |
System.Diagnostics.Debug.WriteLine("--- Files ---") | |
Dim list = Await client.Files.ListFolderAsync(path) | |
' show folders then files | |
For Each item In list.Entries | |
If item.IsFolder Then | |
If item.PathLower = path Then | |
End If | |
System.Diagnostics.Debug.WriteLine("D {0}/", item.Name) | |
End If | |
Next | |
For Each item In list.Entries | |
If item.IsFile Then | |
Dim file = item.AsFile | |
System.Diagnostics.Debug.WriteLine("F{0,8} {1}", file.Size, item.Name) | |
End If | |
Next | |
If list.HasMore Then | |
System.Diagnostics.Debug.WriteLine(" ...") | |
End If | |
Return list | |
End Function | |
''' <summary> | |
''' Downloads a file. | |
''' </summary> | |
''' <remarks>This demonstrates calling a download style api in the Files namespace.</remarks> | |
''' <param name="client">The Dropbox client.</param> | |
''' <param name="folder">The folder path in which the file should be found.</param> | |
''' <param name="file">The file to download within <paramref name="folder"/>.</param> | |
''' <returns></returns> | |
Private Async Function Download(ByVal client As DropboxClient, ByVal folder As String, ByVal file As FileMetadata) As Task | |
System.Diagnostics.Debug.WriteLine("Download file...") | |
Dim response = Await client.Files.DownloadAsync((folder + ("/" + file.Name))) | |
System.Diagnostics.Debug.WriteLine("Downloaded {0} Rev {1}", response.Response.Name, response.Response.Rev) | |
System.Diagnostics.Debug.WriteLine("------------------------------") | |
System.Diagnostics.Debug.WriteLine(Await response.GetContentAsStringAsync) | |
System.Diagnostics.Debug.WriteLine("------------------------------") | |
End Function | |
''' <summary> | |
''' Uploads given content to a file in Dropbox. | |
''' </summary> | |
''' <param name="client">The Dropbox client.</param> | |
''' <param name="folder">The folder to upload the file.</param> | |
''' <param name="fileName">The name of the file.</param> | |
''' <param name="fileContent">The file content.</param> | |
''' <returns></returns> | |
Private Async Function Upload(ByVal client As DropboxClient, ByVal folder As String, ByVal fileName As String, ByVal fileContent As String) As Task | |
System.Diagnostics.Debug.WriteLine("Upload file...") | |
Dim stream = New MemoryStream(System.Text.UTF8Encoding.UTF8.GetBytes(fileContent)) | |
Dim response = Await client.Files.UploadAsync((folder + ("/" + fileName)), WriteMode.Overwrite.Instance, body:=stream) | |
System.Diagnostics.Debug.WriteLine("Uploaded Id {0} Rev {1}", response.Id, response.Rev) | |
End Function | |
''' <summary> | |
''' Lists the items within a folder inside team space. See | |
''' https://www.dropbox.com/developers/reference/namespace-guide for details about | |
''' user namespace vs team namespace. | |
''' </summary> | |
''' <param name="client">The Dropbox client.</param> | |
''' <param name="path">The path to list.</param> | |
''' <returns>The <see cref="Task"/></returns> | |
Private Async Function ListFolderInTeamSpace(ByVal client As DropboxClient, ByVal path As String) As Task | |
' Fetch root namespace info from user's account info. | |
Dim account = Await client.Users.GetCurrentAccountAsync | |
If Not account.RootInfo.IsTeam Then | |
System.Diagnostics.Debug.WriteLine("This user doesn't belong to a team with shared space.") | |
Else | |
Try | |
' Point path root to namespace id of team space. | |
client = client.WithPathRoot(New PathRoot.Root(account.RootInfo.RootNamespaceId)) | |
Await ListFolder(client, path) | |
Catch ex As PathRootException | |
System.Diagnostics.Debug.WriteLine("The user's root namespace ID has changed to {0}", ex.ErrorResponse.AsInvalidRoot.Value) | |
End Try | |
End If | |
End Function | |
''' <summary> | |
''' Uploads a big file in chunk. The is very helpful for uploading large file in slow network condition | |
''' and also enable capability to track upload progerss. | |
''' </summary> | |
''' <param name="client">The Dropbox client.</param> | |
''' <param name="folder">The folder to upload the file.</param> | |
''' <param name="fileName">The name of the file.</param> | |
''' <returns></returns> | |
Private Async Function ChunkUpload(ByVal client As DropboxClient, ByVal folder As String, ByVal fileName As String) As Task | |
System.Diagnostics.Debug.WriteLine("Chunk upload file...") | |
' Chunk size is 128KB. | |
Const chunkSize As Integer = (128 * 1024) | |
' Create a random file of 1MB in size. | |
Dim RND As Random = New Random | |
Dim fileContent = New Byte(((1024 * 1024)) - 1) {} | |
RND.NextBytes(fileContent) | |
Dim stream = New MemoryStream(fileContent) | |
Dim numChunks As Integer = CType(Math.Ceiling((CType(stream.Length, Double) / chunkSize)), Integer) | |
Dim buffer() As Byte = New Byte((chunkSize) - 1) {} | |
Dim sessionId As String = Nothing | |
Dim idx = 0 | |
Do While (idx < numChunks) | |
System.Diagnostics.Debug.WriteLine("Start uploading chunk {0}", idx) | |
Dim byteRead = stream.Read(buffer, 0, chunkSize) | |
Dim memStream As MemoryStream = New MemoryStream(buffer, 0, byteRead) | |
If (idx = 0) Then | |
Dim result = Await client.Files.UploadSessionStartAsync(body:=memStream) | |
sessionId = result.SessionId | |
Else | |
Dim cursor As UploadSessionCursor = New UploadSessionCursor(sessionId, CType((chunkSize * idx), ULong)) | |
If (idx _ | |
= (numChunks - 1)) Then | |
Await client.Files.UploadSessionFinishAsync(cursor, New CommitInfo((folder + ("/" + fileName))), memStream) | |
Else | |
Await client.Files.UploadSessionAppendV2Async(cursor, body:=memStream) | |
End If | |
End If | |
idx = (idx + 1) | |
Loop | |
End Function | |
''' <summary> | |
''' List all members in the team. | |
''' </summary> | |
''' <param name="client">The Dropbox team client.</param> | |
''' <returns>The result from the MembersListAsync call.</returns> | |
Private Async Function ListTeamMembers(ByVal client As DropboxTeamClient) As Task(Of MembersListResult) | |
Dim members = Await client.Team.MembersListAsync | |
For Each member In members.Members | |
System.Diagnostics.Debug.WriteLine("Member id : {0}", member.Profile.TeamMemberId) | |
System.Diagnostics.Debug.WriteLine("Name : {0}", member.Profile.Name) | |
System.Diagnostics.Debug.WriteLine("Email : {0}", member.Profile.Email) | |
Next | |
Return members | |
End Function | |
''' <summary> | |
''' Run tests for user-level operations. | |
''' </summary> | |
''' <param name="client">The Dropbox client.</param> | |
''' <returns>An asynchronous task.</returns> | |
Private Async Function RunUserTests(ByVal client As DropboxClient) As Task | |
Await GetCurrentAccount(client) | |
If Await FolderExists(client) Then | |
Exit Function | |
Else | |
'Target_Folder -> is the folder when you want to guide your users to. | |
Dim path = "/Apps/Target_Folder" | |
Dim folder = Await CreateFolder(client, path) | |
Dim list = Await ListFolder(client, path) | |
Dim firstFile = list.Entries.FirstOrDefault | |
If firstFile.IsFile Then | |
If (Not (firstFile) Is Nothing) Then | |
Await Download(client, path, firstFile.AsFile) | |
End If | |
End If | |
Dim pathInTeamSpace = "/Test" | |
Await ListFolderInTeamSpace(client, pathInTeamSpace) | |
Await Upload(client, path, "Test.txt", "This is a text file") | |
Await ChunkUpload(client, path, "Binary") | |
End If | |
End Function | |
Private Async Function HandleOAuth2Redirect(ByVal http As HttpListener) As Task | |
Dim context = Await http.GetContextAsync | |
' We only care about request to RedirectUri endpoint. | |
While (context.Request.Url.AbsolutePath <> RedirectUri.AbsolutePath) | |
context = Await http.GetContextAsync | |
End While | |
context.Response.ContentType = "text/html" | |
' Respond with a page which runs JS and sends URL fragment as query string | |
' to TokenRedirectUri. | |
Dim File As FileStream = | |
New FileStream(Application.StartupPath & "\HTMLFiles\index.html", FileMode.Open) | |
File.CopyTo(context.Response.OutputStream) | |
context.Response.OutputStream.Close() | |
End Function | |
''' <summary> | |
''' Handle the redirect from JS and process raw redirect URI with fragment to | |
''' complete the authorization flow. | |
''' </summary> | |
''' <param name="http">The http listener.</param> | |
''' <returns>The <see cref="OAuth2Response"/></returns> | |
Private Async Function HandleJSRedirect(ByVal http As HttpListener) As Task(Of OAuth2Response) | |
Dim context = Await http.GetContextAsync | |
' We only care about request to TokenRedirectUri endpoint. | |
While (context.Request.Url.AbsolutePath <> JSRedirectUri.AbsolutePath) | |
context = Await http.GetContextAsync | |
End While | |
Dim redirectUri = New Uri(context.Request.QueryString("url_with_fragment")) | |
Dim result = DropboxOAuth2Helper.ParseTokenFragment(redirectUri) | |
Return result | |
End Function | |
''' <summary> | |
''' Gets the dropbox access token. | |
''' <para> | |
''' This fetches the access token from the applications settings, if it is not found there | |
''' (or if the user chooses to reset the settings) then the UI in <see cref="LogSettings.TabPage2"/> is | |
''' displayed to authorize the user. | |
''' </para> | |
''' </summary> | |
''' <returns>A valid access token or null.</returns> | |
Private Async Function GetAccessToken() As Task(Of String) | |
Dim ThisR As String = MsgBox("Reset settings (Y/N) ", MsgBoxStyle.YesNo) | |
If (ThisR = MsgBoxResult.Yes) Then | |
My.Settings.Reset() | |
End If | |
'Console.WriteLine() | |
Dim accessToken = My.Settings.AccessToken | |
If String.IsNullOrEmpty(accessToken) Then | |
Try | |
System.Diagnostics.Debug.WriteLine("Waiting for credentials.") | |
Dim state = Guid.NewGuid.ToString("N") | |
Dim authorizeUri = | |
DropboxOAuth2Helper.GetAuthorizeUri(OAuthResponseType.Token, ApiKey, RedirectUri, state:=state, | |
forceReapprove:=False, disableSignup:=False, requireRole:=Nothing, | |
forceReauthentication:=False) | |
Dim http = New HttpListener | |
http.Prefixes.Add(LoopBackHost) | |
http.Start() | |
System.Diagnostics.Process.Start(authorizeUri.ToString) | |
' Handle OAuth redirect and send URL fragment to local server using JS. | |
Await HandleOAuth2Redirect(http) | |
' Handle redirect from JS and process OAuth response. | |
Dim result = Await HandleJSRedirect(http) | |
If (result.State <> state) Then | |
' The state in the response doesn't match the state in the request. | |
Return Nothing | |
End If | |
System.Diagnostics.Debug.WriteLine("and back...") | |
' Bring console window to the front. | |
SetForegroundWindow(GetConsoleWindow) | |
accessToken = result.AccessToken | |
Dim uid = result.Uid | |
System.Diagnostics.Debug.WriteLine("Uid: {0}", uid) | |
My.Settings.AccessToken = accessToken | |
My.Settings.Uid = uid | |
My.Settings.Save() | |
Catch e As Exception | |
System.Diagnostics.Debug.WriteLine("Error: {0}", e.Message) | |
Return Nothing | |
End Try | |
End If | |
Return accessToken | |
End Function | |
End Class | |
'Now create a form [Windows Form],add Button2 control on it, and place this code | |
Public Class MainForm | |
Private Async Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click | |
Dim ThisDropBox As New DropBoxC | |
Try | |
Await ThisDropBox.Run | |
Catch ex As Dropbox.Api.DropboxException | |
MsgBox(ex.Message) | |
End Try | |
End Sub | |
End Class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment