Het Google Drive API 'filesystem'
Home

Het Google Drive API 'filesystem'

Het Google Drive API 'filesystem'

Net als bij Google Documenten, is Google Drive in principe één grote zak met bestanden en Google Drive stelt je in staat om deze bestanden te taggen. Nu is de gewone gebruiker gewoon aan een bestandsstructuur zoals in bijvoorbeeld in Explorer. Dus bedacht Google een tussenoplossing die bestaat uit een losse bestandsstructuur (alle bestanden in één zak) en het gebruik van labels, om het enigszins te doen lijken op een boomstructuur-bestandsmap systeem.

Beschrijving

Filmpje: Het Google Drive API filesystem

Op het Drive platform, wordt gebruikt gemaakt van een model dat gebaseerd is op file IDs — en niet op de trasitionele folder hierarchie — om te kunnen werken met Google Drive bestanden en folders. Meer informatie hierover vind je op Work with Folders en Manage File Metadata.

Eigenlijk is het Google systeem zeer geschikt voor Myaa. Maar voorlopig gaan we daar niet verder op in. We gaan leren werken met Google Drive vanuit het perspectief van een filesysteem georganiseerd als een boomstructuur. Een interessant artikel over de mogelijkheden van Google Drive's filesysteem: Giving up the file system with Google Docs (or Office Web Apps). En een artikel over hoe je je bestanden organiseert op Google Drive: How to Organize Google Drive – A Best Practice Guide for Teams.

Wat hieraan voorafging

Vooraleer aan deze les te beginnen moet je de stappen beschreven in Google Drive API - Wat voorafging doorlopen hebben. Vooral het gedeelte over het herstructureren van de code voor hergebruik.

Overzicht bestanden

Google Drive API filesystem voorbeeld
Google Drive API filesystem voorbeeld

Alle bestanden en folders in één 'zak'

Met het volgende voorbeelden willen we inzicht krijgen in het 'filesystem' van de Google Drive.

De methode showFeedback is een helper functie die als parameter een tekstboodschap aanneemt. Deze functie verifiëert als er een html div element met id="feedback" bestaat. Indien niet, wordt dat html element toegevoegd aan het body element. Daarna wordt er in dat element een p element gemaakt waarin de tekstboodschap wordt geplaatst. Deze functie staat in het bestand met de naam helpers.js in de js map:

/**
 * Helper function showFeedback
 * Append a p element to the feedback html element
 * with the given text as its text node.
 *
 * @param {string} text Text to be placed in the p element.
 */
function showFeedback(text) {
    var feedback = document.getElementById('feedback');
    if (!feedback) {
        feedback = document.createElement('div');
        document.body.appendChild(feedback);
    }
    var p = document.createElement('p');
    var textContent = document.createTextNode(text);
    p.appendChild(textContent);
    feedback.appendChild(p);
}

We beginnen met de methode showAllInGoogleDrive. Deze methode staat in het bestand met de naam google-drive-api-uitproberen.html in de root map. Hiermee willen we laten zien dat alle bestanden in één 'zak' zitten. We gebruiken de gapi.client.drive.files.list methode en geven als argument mee dat we maximum 100 bestanden ophalen en dat we de id, de naam, het soort van bestand en het mimetype willen ophalen. Als dat gebeurt is tonen we in de then methode de response van de API call en daarna de lijst van de opgehaalde bestanden:

/**
* Show files in the Google Drive
*/
function showAllInGoogleDrive() {
    var explorer = clearExplorer();
    // if no folder info is passed get it from Google Drive API
    // id, name, kind and mimeType are the only possible values
    // you can ommit altogether the fields property
    gapi.client.drive.files.list({
        'pageSize': 100,
        'fields': "nextPageToken, files(id, name, kind, mimeType)"
    }).then(function(files) {
        showFeedback(JSON.stringify(files, 4));
        folder = files.result.files;
        folder.map(function(item) {
            var p = document.createElement('p');
            var textContent = document.createTextNode(item.name);
            p.appendChild(textContent);
            explorer.appendChild(p);
        });
    })
 }

De call naar de Google Drive API staat in het bestand met de naam google-drive-api-uitproberen.html in de root map:

/**
 * Load Drive API client library.
 * Samples: https://advancedweb.hu/2015/05/26/accessing-google-drive-in-javascript/
 */
function makeDriveApiCall() {
    gapi.client.load('drive', 'v3', showAllInGoogleDrive);
}

En deze methode roepen we op in de handleInitialSignInStatus methode op de html pagina met de naam google-drive-api-uitproberen.html in de root map:

/**
 * Handle the initial sign-in state.
 * This method is called by the OAuth initAuth method and is
 * called once the user is signed in succesfully
 */
var handleInitialSignInStatus = function() {
    updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
    signinButton.addEventListener("click", signIn);
    signoutButton.addEventListener("click", signOut);
    makeDriveApiCall();
}

Als we de pagina in de browser laden worden we gevraagd om ons aan te melden met een Google Account en worden vervolgens alle bestanden en folders in onze Google Drive getoond, ook de folders en files die we gedeleted hebben:

Google Drive API - All files and folders
Google Drive API - All files and folders

We vergelijken dit met wat er op My Drive op Google staat. De map myap en php en het bestand myap.png staan effectief op mijn Google Drive:

Google Drive - My Drive
Google Drive - My Drive

Als ik de prullenbak op mijn Google Drive open, zie ik al die andere bestanden en folders die ik met de Google Drive API heb opgehaald:

Google Drive - Bin
Google Drive - Bin

In de feedback tonen we een JSON voorstelling van het resultaat dat de API call heeft geretourneerd.

Google Drive API - response in JSON
Google Drive API - response in JSON

Ik heb de feedback eerst leesbaar gemaakt met JSON Formatter:

{
   "result": {
      "files": [
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFMXI1TzZEXzBnRjA",
            "name": "php",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFNG1wcjlXM0ozcnM",
            "name": "php",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFZVYyRFR4ZlB2dTA",
            "name": "it",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFS2g3cTdoWUEyaWc",
            "name": "myap/it",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFYVFpS3lzbVczVmM",
            "name": "New Folder",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFNHNTTnhNLV83QWM",
            "name": "myap",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFYWdfaFZzd2RCRUk",
            "name": "myap",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFRUdJZmUyTjQ1RTA",
            "name": "myap",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFeFQxTEkxdVA0eW8",
            "name": "myap",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFZDN0UTlVVUtIWnc",
            "name": "test",
            "mimeType": "application/vnd.google-apps.folder"
         },
         {
            "kind": "drive#file",
            "id": "0B-Of_wHoUhbFU1JtWFZwRHZOeVE",
            "name": "myap.png",
            "mimeType": "image/png"
         },
         {
            "kind": "drive#file",
            "id": "1B66lJXFwjVJvHCDRaFKuynjBqM2Y_aSM945_YyoNOTw",
            "name": "Vertaald exemplaar van test",
            "mimeType": "application/vnd.google-apps.document"
         },
         {
            "kind": "drive#file",
            "id": "1phcqN7aowXO50rjQXBw1FPWC-NElNxlF0F1ZRe8WFqk",
            "name": "test",
            "mimeType": "application/vnd.google-apps.document"
         },
         {
            "kind": "drive#file",
            "id": "1OVg0x97RpCUxuCfxXhUL_16wp9RDCbkyDpaw1ZpHFqM",
            "name": "test",
            "mimeType": "application/vnd.google-apps.document"
         }, ...

En zo gaat dat verder tot de laaste folder of bestand in de Google Drive.

Trashed

Ik ben niet geïnteresseerd in de verwijderde folders en bestanden. Ik kan het q (query) veld gebruiken om voorwaarden aan de API call toe te voegen. Hier zie je hoe je verwijderde bestanden en folders uitsluit:

/**
 * Show files in the Google Drive that have not been deleted
 */
function showAllNotTrashedInGoogleDrive() {
    var explorer = clearExplorer();
    // if no folder info is passed get it from Google Drive API
    // id, name, kind and mimeType are the only possible values
    // you can ommit altogether the fields property
    gapi.client.drive.files.list({
        'pageSize': 100,
        'fields': "nextPageToken, files(id, name, kind, mimeType)",
        q: "trashed = false"
    }).then(function(files) {
        showFeedback(JSON.stringify(files, 4));
        folder = files.result.files;
        folder.map(function(item) {
            var p = document.createElement('p');
            var textContent = document.createTextNode(item.name);
            p.appendChild(textContent);
            explorer.appendChild(p);
        });
    })
}        

En we roepen nu deze methode op als callback in de api call:

/**
 * Load Drive API client library.
 * Samples: https://advancedweb.hu/2015/05/26/accessing-google-drive-in-javascript/
 */
function makeDriveApiCall() {
    gapi.client.load('drive', 'v3', showAllNotTrashedInGoogleDrive);
}

En dit is het resultaat:

Google Drive API - All not deleted files and folders
Google Drive API - All not deleted files and folders

De volledige code

De JS bestanden in de js map

helpers.js

/**
 * Helper function showFeedback
 * Append a p element to the feedback html element
 * with the given text as its text node.
 *
 * @param {string} text Text to be placed in the p element.
 */
function showFeedback(text) {
    var feedback = document.getElementById('feedback');
    if (!feedback) {
        feedback = document.createElement('div');
        document.body.appendChild(feedback);
    }
    var p = document.createElement('p');
    var textContent = document.createTextNode(text);
    p.appendChild(textContent);
    feedback.appendChild(p);
}

google-oauth-api.js

function handleClientLoad() {
    // Load the API client and auth library
    gapi.load('client:auth2', initAuth);
}

function initAuth() {
    // gapi.client.setApiKey(apiKey);
    gapi.auth2.init({
            client_id: clientId,
            scope: scopes.join(' '),
            immediate: true
        }).then(function() {
            // Listen for sign-in state changes.
            gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
        }).then(handleInitialSignInStatus);
}

function updateSigninStatus(isSignedIn) {
    if (isSignedIn) {
        signinButton.style.display = 'none';
        signoutButton.style.display = 'block';
    }
    else {
        signinButton.style.display = 'block';
        signoutButton.style.display = 'none';
        clearUserProfile();
        clearExplorer();
    }
}

function signIn(event) {
    gapi.auth2.getAuthInstance().signIn();
}

function signOut(event) {
    gapi.auth2.getAuthInstance().signOut();
}

De webpagina google-drive-api-uitproberen.html

<!doctype html>
<html lang="nl">
<head>
    <meta charset="UTF-8">
    <title>Google Drive API uitproberen</title>
    <script type="text/javascript" src="js/google-oauth-api.js"></script>
    <script type="text/javascript" src="js/helpers.js"></script>
    <script>
        var apiKey = 'AIzaSyAmd2VnWexHajlyARnDykoXQUHyGg24RsM';
        var clientId = '420594077145-po45ldmitjnulihvt5309kmeoltb9pmq.apps.googleusercontent.com';
        var scopes = ['profile', 'https://www.googleapis.com/auth/drive.file'];

        /**
         * Load Drive API client library.
         * Samples: https://advancedweb.hu/2015/05/26/accessing-google-drive-in-javascript/
         */
        function makeDriveApiCall() {
            gapi.client.load('drive', 'v3', showAllNotTrashedInGoogleDrive);
        }

        /**
         * Show files in the Google Drive
         */
        function showAllInGoogleDrive() {
            var explorer = clearExplorer();
            // if no folder info is passed get it from Google Drive API
            // id, name, kind and mimeType are the only possible values
            // you can ommit altogether the fields property
            gapi.client.drive.files.list({
                'pageSize': 100,
                'fields': "nextPageToken, files(id, name, kind, mimeType)",
                q: "trashed = false"
            }).then(function(files) {
                showFeedback(JSON.stringify(files, 4));
                folder = files.result.files;
                folder.map(function(item) {
                    var p = document.createElement('p');
                    var textContent = document.createTextNode(item.name);
                    p.appendChild(textContent);
                    explorer.appendChild(p);
                });
            })
        }

        /**
         * Show files in the Google Drive that have not been deleted
         */
        function showAllNotTrashedInGoogleDrive() {
            var explorer = clearExplorer();
            // if no folder info is passed get it from Google Drive API
            // id, name, kind and mimeType are the only possible values
            // you can ommit altogether the fields property
            gapi.client.drive.files.list({
                'pageSize': 100,
                'fields': "nextPageToken, files(id, name, kind, mimeType)",
                q: "trashed = false"
            }).then(function(files) {
                showFeedback(JSON.stringify(files, 4));
                folder = files.result.files;
                folder.map(function(item) {
                    var p = document.createElement('p');
                    var textContent = document.createTextNode(item.name);
                    p.appendChild(textContent);
                    explorer.appendChild(p);
                });
            })
        }

        /**
         * Clear files and folders in the Explorer
         */
        function clearExplorer() {
            var list = document.querySelector('#list');
            list.innerHTML = '';
            return list;
        }

        /**
         * Handle the initial sign-in state.
         * This method is called by the OAuth initAuth method and is
         * called once the user is signed in succesfully
         */
        var handleInitialSignInStatus = function() {
            updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
            signinButton.addEventListener("click", signIn);
            signoutButton.addEventListener("click", signOut);
            makeDriveApiCall();
        }
    </script>
</head>
<body>
    <button id="signin-button">Aanmelden</button>
    <button id="signout-button">Afmelden</button>
    <div id="explorer">
        <div id="list"></div>
    </div>
    <div id="feedback">
    </div>
    <script>
        var signinButton = document.getElementById('signin-button');
        var signoutButton = document.getElementById('signout-button');
    </script>
    <script src="https://apis.google.com/js/api.js?onload=handleClientLoad"></script>
</body>
</html>

Je vind die code terug op mijn team workspace.

JI
2016-10-20 15:39:29