A few weeks ago I posted a message asking if anyone had written code to upload 
and download files to Dropbox. Got no responses other than “the API looks like 
it is easy to do”. 

Today I spent time writing a couple of methods to allow uploading and 
downloading files from Dropbox with native 4D commands using the Dropbox v2 
API. And people were right, it was not too difficult. The v2 API is implemented 
very nicely and documented fairly well. I found a few documentation errors, but 
they were easily dealt with. 

4D v17 provided all the commands needed to make it all work with very little 
code. Doing this with NTK would easily take 3 times the amount of code.

My current needs are very simple. I want to upload a file to Dropbox and 
replace any existing file if necessary. Dropbox maximum file size for a single 
upload operation is 150MB. That’s more than enough for my needs. But if you 
want to upload larger files — up to the Dropbox API max size of 350MB — you’ll 
have to implement an “upload session”. 

Download requirements are also simple. Just download a file from a Dropbox path 
to a path on your hard drive. Dropbox paths are in POSIX format. 

The Dropbox v2 API uses OAuth 2, but that basically boils down to creating an 
“App” and getting an “access token” the you use with all the API calls. I’ll 
leave it up to you to go read the docs and set that all up. It’s easy. 

The code uses dot notation, but with a little work it could be ported to work 
with older versions for 4D probably back to v14. Code is cross-platform without 
any extra effort needed.

Here is me giving back to the group so you don’t have to spend a day developing 
and testing code. If others implement more of the Dropbox v2 API, please post 
it to the iNUG to help others.

  // ===========================================
  // PROJECT METHOD: Dropbox_UploadFile

  // PARAMETERS: $0 = results object
  // $1 = dropbox access token
  // $2 = dropbox path
  // $3 = file path

  // DESCRIPTION: Uploads a file to Dropbox using the v2 API
  // Max upload size in a single transfer is 150MB.

  // https://www.dropbox.com/developers/documentation/http/documentation

  // CREATED BY: Tim Nevels, Innovative Solutions ©2019
  // DATE: 3/8/19
  // LAST MODIFIED: 
  // ============================================

C_OBJECT($0;$results_o)
C_TEXT($1;$dropboxAccessToken_t)
C_TEXT($2;$dropboxPath_t)
C_TEXT($3;$filePath_t)
$dropboxAccessToken_t:=$1
$dropboxPath_t:=$2
$filePath_t:=$3

  // declare local variables
C_TEXT($headerValue_t;$requestURL_t;$response_t)
C_LONGINT($statusCode_l)
C_BLOB($content_x)
C_OBJECT($headerValue_o;$response_o)
ARRAY TEXT($headerName_at;0)
ARRAY TEXT($headerValue_at;0)

  // setup http header
APPEND TO ARRAY($headerName_at;"Authorization")
APPEND TO ARRAY($headerValue_at;"Bearer "+$dropboxAccessToken_t)

  // set upload header values
APPEND TO ARRAY($headerName_at;"Content-Type")
APPEND TO ARRAY($headerValue_at;"application/octet-stream”)

APPEND TO ARRAY($headerName_at;"Dropbox-API-Arg")
$headerValue_o:=New object(\
"path";$dropboxPath_t;\
"mode";"add";\
"autorename";False)  // overwrite any existing file
$headerValue_t:=JSON Stringify($headerValue_o)
APPEND TO ARRAY($headerValue_at;$headerValue_t)

  // set url
$requestURL_t:="https://content.dropboxapi.com/2/files/upload";

  // load the file
DOCUMENT TO BLOB($filePath_t;$content_x)

  // check file size
If (BLOB size($content_x)>(1024*1024*149))  // over 149MB, too close to limit 
to try
        $results_o:=New object(\
        "success";False;\
        "statusCode";408;\
        "errorMessage";"File is to large to upload in one piece")
Else 
          // upload the file
        HTTP SET OPTION(HTTP compression;1)  // do compression
        HTTP SET OPTION(HTTP timeout;60*10)  // 10 minute timeout
        $statusCode_l:=HTTP Request(HTTP POST 
method;$requestURL_t;$content_x;$response_t;$headerName_at;$headerValue_at)
        
          // build results object
        Case of 
                : ($statusCode_l=200)  // upload was a success
                        $results_o:=New object(\
                        "success";True;\
                        "statusCode";$statusCode_l;\
                        "errorMessage";"File upload was successful")
                        
                : ($statusCode_l=409)  // endpoint specific problem
                        $response_o:=JSON Parse($response_t)
                        $results_o:=New object(\
                        "success";False;\
                        "statusCode";$statusCode_l;\
                        "errorMessage";$response_o.error_summary)
                        
                Else   // other problem
                        $results_o:=New object(\
                        "success";False;\
                        "statusCode";$statusCode_l;\
                        "errorMessage";"HTTP Request failed"+Char(Carriage 
return)+Char(Carriage return)+\
                        $response_t)
        End case 
End if 

  // return results
$0:=$results_o


  // ===========================================
  // PROJECT METHOD: Dropbox_DownloadFile

  // PARAMETERS:  $0 = results object
  // $1 = dropbox access token
  // $2 = dropbox path
  // $3 = file path

  // DESCRIPTION: Downloads a file from Dropbox using the v2 API

  // https://www.dropbox.com/developers/documentation/http/documentation

  // CREATED BY: Tim Nevels, Innovative Solutions ©2019
  // DATE: 3/8/19
  // LAST MODIFIED: 
  // ============================================

C_OBJECT($0;$results_o)
C_TEXT($1;$dropboxAccessToken_t)
C_TEXT($2;$dropboxPath_t)
C_TEXT($3;$filePath_t)
$dropboxAccessToken_t:=$1
$dropboxPath_t:=$2
$filePath_t:=$3

  // declare local variables
C_TEXT($headerValue_t;$requestURL_t;$content_t;$response_t)
C_LONGINT($statusCode_l)
C_BLOB($response_x)
C_OBJECT($response_o;$headerValue_o)
ARRAY TEXT($headerName_at;0)
ARRAY TEXT($headerValue_at;0)

  // setup http header
APPEND TO ARRAY($headerName_at;"Authorization")
APPEND TO ARRAY($headerValue_at;"Bearer "+$dropboxAccessToken_t)

  // set download header value
APPEND TO ARRAY($headerName_at;"Dropbox-API-Arg")
$headerValue_o:=New object(\
"path";$dropboxPath_t)
$headerValue_t:=JSON Stringify($headerValue_o)
APPEND TO ARRAY($headerValue_at;$headerValue_t)

  // set url
$requestURL_t:="https://content.dropboxapi.com/2/files/download";

  // download the file
HTTP SET OPTION(HTTP compression;1)  // do compression
HTTP SET OPTION(HTTP timeout;60*10)  // 10 minute timeout
$statusCode_l:=HTTP Request(HTTP POST 
method;$requestURL_t;$content_t;$response_x;$headerName_at;$headerValue_at)

  // build results object
Case of 
        : ($statusCode_l=200)  // download was a success
                $results_o:=New object(\
                "success";True;\
                "statusCode";$statusCode_l;\
                "errorMessage";"File download was successful")
                
        : ($statusCode_l=409)  // endpoint specific problem
                $response_t:=BLOB to text($response_x;UTF8 text without length)
                $response_o:=JSON Parse($response_t)
                $results_o:=New object(\
                "success";False;\
                "statusCode";$statusCode_l;\
                "errorMessage";$response_o.error_summary)
                
        Else   // other problem
                $results_o:=New object(\
                "success";False;\
                "statusCode";$statusCode_l;\
                "errorMessage";"HTTP Request failed"+Char(Carriage 
return)+Char(Carriage return)+\
                $response_t)
End case 

  // convert response to a file
If ($statusCode_l=200)
        BLOB TO DOCUMENT($filePath_t;$response_x)
End if 

  // return results
$0:=$results_o



Tim

*****************************************
Tim Nevels
Innovative Solutions
785-749-3444
[email protected]
*****************************************

**********************************************************************
4D Internet Users Group (4D iNUG)
Archive:  http://lists.4d.com/archives.html
Options: https://lists.4d.com/mailman/options/4d_tech
Unsub:  mailto:[email protected]
**********************************************************************

Reply via email to