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] **********************************************************************

