2
votes

I'm working with the TCL syntax for uploading a file to a Google Drive subdirectory using cURL. Based on documentation there is a property called parent that holds the subfolder id. It works fine in the "Try the API section" - and my code below works fine if I remove the parents parameter (then, the file is uploaded to the GDrive root folder).

This is how the parameter should look like based on documentation:

parents : [{"id" : "0B-b5yS-0xCQjVEcyMm9hYmtqd0k"}]

Now I want to adapt this to my current code but it errors occur. I assume the issue is related to TCL syntax, but as I'm not that familiar with the language I'm completely lost now after spending hours with try&error to get it working. What I try to do is to set a parameter fileMetaData that holds all necessary values for the metadata (so even the parent folder list), furthermore I define a parameter curlCommand that stores the final cURL statement. Within that curlCommand I provide the fileMetaData and finally I execute the command with cURL within an eval exec statement. I think it is related to substitution? But I'm really lost. I've tried it with double-quotes and even with backslashes before the curly braces and the square brackets. I always get an error.

This is the current code:

set fileMetaData "metadata={name : '$backupFile', title : '$fileName', \
                            description : 'Backup file from $today', \
                            parents : [{id : '0B-b5yS-0xCQjVEcyMm9hYmtqd0k'}] }"

set curlCommand "-H \"GData-Version: 3.0\" \
                 -H \"Authorization: Bearer $accessToken\" \
                 -F \"$fileMetaData;type=application/json;charset=UTF-8\" \
                 -F \"file=@$backupFile\" \
                   https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart"

catch { eval exec /usr/local/addons/prtz/curl -k $curlCommand}    

The error message I get while running the code is:

invalid command name "id: '0B-b5yS-0xCQjVEcyMm9hYmtqd0k'"
while executing "{id: '0B-b5yS-0xCQjVEcyMm9hYmtqd0k'}"

Maybe important: I strictly have to use native TCL 8.2 without any additional libraries (i.e. for JSON support). I appreciate any input that helps to figure how to solve!

Thanks.

1
8.2 is vastly long out of support. - Donal Fellows
I know... but can't influence it. There are manufacturers out there who are still deliver their hardware with this version even in 2017. - Schlager Bar

1 Answers

1
votes

It's going to be easiest to build that command line bit by bit with list commands.

# Your immediate problem was the square brackets building this value; backslash needed
set fileMetaData "{name : '$backupFile', title : '$fileName', \
                   description : 'Backup file from $today', \
                   parents : \[{id : '0B-b5yS-0xCQjVEcyMm9hYmtqd0k'}\] }"

set curlCommand {/usr/local/addons/prtz/curl -k}
lappend curlCommand -H "GData-Version: 3.0"
lappend curlCommand -H "Authorization: Bearer $accessToken"
lappend curlCommand -F "metadata=$fileMetaData;type=application/json;charset=UTF-8"
lappend curlCommand -F "file=@$backupFile"
lappend curlCommand "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart"

catch { eval exec $curlCommand }
# If you were using a supported Tcl (8.5 and later) I'd say use this instead:
#     catch { exec {*}$curlCommand }
# but since we've built with lappend there's no surprises anyway.

It's much easier to build lists correctly using the list commands. In this case, you could also build the metadata using format:

set parentID 0B-b5yS-0xCQjVEcyMm9hYmtqd0k
set description "Backup file from $today"

set fileMetaData [format \
        {{name : '%s', title : '%s', description : '%s', parents : [{id : '%s'}]}} \
        $backupFile $fileName $description $parentID] 

(Another option would be subst -nocommands, but for this case I think format is neater.)