1
votes

I am trying to upload a folder to google drive with keeping its directory structure by using javascript drive api. I achieved to upload all files but not folders in a folder. Also I achieved to upload an empty folder to google drive by drive api. However I could not find a resource that explain uploading a folder with keeping its all directory structure. For example I have a folder like that: (I added a link to show my example folder. I could not add direct image because of my low reputation.) http://postimg.org/image/h52bvb71v/

But When I choose the folder, I can just upload the .txt files. At least google drive api Javascript Quickstart provides me that code. I dont want to ruin structure of folder and I want to upload it to drive with original structure. Do you have any idea how can I do this with google drive api and javascript. Thanks.

Here is my code. It just uploads the files inside folders but not the folders.

<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<script type="text/javascript">
    var CLIENT_ID = 'xxxxxxxxxxxxxxxxxxx';
    var SCOPES = 'https://www.googleapis.com/auth/drive';

    /**
     * Called when the client library is loaded to start the auth flow.
     */
    function handleClientLoad() {
        window.setTimeout(checkAuth, 1);
    }

    /**
     * Check if the current user has authorized the application.
     */
    function checkAuth() {
        gapi.auth.authorize(
            { 'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': true },
            handleAuthResult);
    }

    /**
     * Called when authorization server replies.
     *
     * @param {Object} authResult Authorization result.
     */
    function handleAuthResult(authResult) {
        var authButton = document.getElementById('authorizeButton');
        var filePicker = document.getElementById('filePicker');
        authButton.style.display = 'none';
        filePicker.style.display = 'none';
        if (authResult && !authResult.error) {
            // Access token has been successfully retrieved, requests can be sent to the API.
            filePicker.style.display = 'block';
            filePicker.onchange = uploadFile;
        } else {
            // No access token could be retrieved, show the button to start the authorization flow.
            authButton.style.display = 'block';
            authButton.onclick = function () {
                gapi.auth.authorize(
                    { 'client_id': CLIENT_ID, 'scope': SCOPES, 'immediate': false },
                    handleAuthResult);
            };
        }
    }

    /**
     * Start the file upload.
     *
     * @param {Object} evt Arguments from the file selector.
     */
    function uploadFile(evt) {
        gapi.client.load('drive', 'v2', function () {
            var output = document.getElementById('output');


            var files = evt.target.files; // FileList object

            var totalFiles = files.length; // important

            for (var i = 0; i < totalFiles; i++) {
                var file = evt.target.files[i];
                insertFile(file);
          /*      if (file.isFile) {
                    document.write("OLDUUUUUUU");
                } else if (file.isDirectory) {
                    document.write("haydaaaaa");
                }*/
                console.debug(file.webkitRelativePath);
                output.innerText = output.innerText + file.webkitRelativePath + "\n";
            }

        //    var file = evt.target.files[0];
         //   insertFile(file);
        });
    }

    /**
     * Insert new file.
     *
     * @param {File} fileData File object to read data from.
     * @param {Function} callback Function to call when the request is complete.
     */
    function insertFile(fileData, callback) {
        const boundary = '-------314159265358979323846';
        const delimiter = "\r\n--" + boundary + "\r\n";
        const close_delim = "\r\n--" + boundary + "--";

        var reader = new FileReader();
        reader.readAsBinaryString(fileData);
        reader.onload = function (e) {
            var contentType = fileData.type || 'application/octet-stream';
            var metadata = {
                'title': fileData.name,
                'mimeType': contentType,
                'parents': [{ "id": "0B-WlbPCzbAQpfmhpNXVRWmFlT2daWC1xNEUyQUJEbnViZThYUXVzMFpvdTNuYTc4aDJmb0E" }]
            };

            var base64Data = btoa(reader.result);
            var multipartRequestBody =
                delimiter +
                'Content-Type: application/json\r\n\r\n' +
                JSON.stringify(metadata) +
                delimiter +
                'Content-Type: ' + contentType + '\r\n' +
                'Content-Transfer-Encoding: base64\r\n' +
                '\r\n' +
                base64Data +
                close_delim;

            var request = gapi.client.request({
                'path': '/upload/drive/v2/files',
                'method': 'POST',
                'params': { 'uploadType': 'multipart' },
                'headers': {
                    'Content-Type': 'multipart/mixed; boundary="' + boundary + '"'
                },
                'body': multipartRequestBody
            });

         /*   var request = gapi.client.request({
                'path': '/drive/v2/files',
                'method': 'POST',
                'params': { 'uploadType': 'multipart' },
                'body': {
                    "title": "cat",
                    "mimeType": "application/vnd.google-apps.folder",
                    "description": "Some"
                }
            });*/

            if (!callback) {
                callback = function (file) {
                    console.log(file)
                };
            }
            request.execute(callback);
        }
    }

</script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=handleClientLoad"></script>
</head>
<body>
 <!--Add a file picker for the user to start the upload process 
     <input type="file" name="files[]" multiple directory webkitdirectory mozdirectory>
    -->
 <div>
    <input type="file" id="filePicker" multiple directory webkitdirectory mozdirectory />
    <input type="button" id="authorizeButton" style="display: none" value="Authorize" />
</div>      
<div id="output"></div>

1
code? http trace? error messages? anything that will keep your question alive? - pinoyyid
I just added my code for uploading can you check it again? - chaos

1 Answers

5
votes

the api does not support what you want. however as you found out you can create empty folders. then recursively create the needed folders and upload files to it.