Skip to content

Instantly share code, notes, and snippets.

@facebookegypt
Created April 27, 2020 21:53
Show Gist options
  • Save facebookegypt/6ed1bef18dfac7a73939d39d381f1550 to your computer and use it in GitHub Desktop.
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.
'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