Version 2 of Dropbox

Updated 2018-09-20 12:56:16 by jdc

Access to your personal Dropbox

I recently wanted to download and upload files from my Dropbox. Turns out that this is easy to do in Tcl.

If all you need is access to your own Dropbox, you don't have to implement the authorization process. Instead:

  1. Go to https://www.dropbox.com/ and sign into your account.
  2. Go to the "App Console" at https://www.dropbox.com/developers/apps
  3. Click on "Create app".
    1. What type of app do you want to create? Select "Dropbox API app".
    2. What type of data does your app need to store on Dropbox? Select "Files and datastores".
    3. Can your app be limited to its own folder? Select according to your preference. For this example, choose "Yes - My app only needs access to files it creates."
    4. If you chose "No" to the previous question, Dropbox will also ask you what types of files the app needs to access. For full access, select "All file types -- My app needs access to a user's full Dropbox."
    5. Provide an app name (for simplicity, just a random string).
  4. After creating the app, find the "OAuth 2" section.
  5. Click on "Generate access token".
  6. You will get the access token (a very long string). Copy this token to your app.

Prerequisites

You need HTTP and TLS:

 package require http
 package require tls
 http::register https 443 ::tls::socket

File Upload

Now let's upload some file to your Dropbox. The basic idea is:

  • The base URL for uploading is "https://api-content.dropbox.com/1/files_put/auto ", everything after that is the path into your Dropbox. If you chose that the app is limited to its own folder, this path is "chrooted" to the "/Apps/<app-name>" folder in your Dropbox.
  • Note that the file name must be URL-encoded, e.g., space characters must be replaced with %20.
  • Send an HTTP PUT-request for the desired URL with the file contents as body.
  • The HTTP headers must include a line "Authorization: Bearer ${access_token}", where access_token is copied from above.

Assuming that $file is the URL-encoded path to the file in your Dropbox and $content is the data you would like to upload, this then looks like:

 set file "/test.txt"
 set contents "Hello World!"
 set access_token "<copy and paste from above>"
 set base "https://api-content.dropbox.com/1/files_put/auto"
 set url "${base}${file}"
 set contentLength [string length $content]
 set contentType "application/binary"
 set access_token "<copy and paste from above>"
 set headers [list Content-Length $contentLength Host api-content.dropbox.com Authorization "Bearer $access_token"]

 set token [http::geturl $url -headers $headers -method PUT -type $contentType -query $content]
 http::wait $token

If the upload is successful, the server responds with a 200 status code and an HTTP body with some useful information in JSON format.

File Download

File download is even easier:

  • The base URL for downloading is "https://api-content.dropbox.com/1/files/auto ". (Same rules as above.)
  • Send an HTTP GET-request for the desired URL.
  • The HTTP headers must include a line "Authorization: Bearer ${access_token}", where access_token is copied from above.

Again assuming that $file is the URL-encoded path to the file in your Dropbox:

 set file "/test.txt"
 set access_token "<copy and paste from above>"
 set base "https://api-content.dropbox.com/1/files/auto"
 set url "${base}${file}"
 set headers [list Host api-content.dropbox.com Authorization "Bearer $access_token"]

 set token [http::geturl $url -headers $headers]
 http::wait $token

If the download is successful, the server responds with a 200 status code, and the HTTP body will contain the file contents:

 set contents [http::data $token]

Some file metadata is also returned in the server response's "x-dropbox-metadata" header, again in JSON format.

Authorization

Things are more complex if you would like to access someone else's Dropbox. The user must be redirected to Dropbox' Web site (which has to be done outside Tcl) to authorize access. The authorization flow is described in the documentation referenced below.

References