How do I search sub-folders and sub-sub-folders in Google Drive?

后端 未结 4 1952
暗喜
暗喜 2020-11-22 13:29

This is a commonly asked question.

The scenario is:-

folderA____ folderA1____folderA1a
       \\____folderA2____folderA2a
                    \\___fo         


        
4条回答
  •  一整个雨季
    2020-11-22 14:00

    Sharing a javascript solution using recursion to build an array of folders, starting with the first level folder and moving down the hierarchy. This array is composed by recursively cycling through the parent Id's of the file in question.

    The extract below makes 3 separate queries to the gapi:

    1. get the root folder id
    2. get a list of folders
    3. get a list of files

    the code iterates through the list of files, then creating an array of folder names.

    const { google } = require('googleapis')
    const gOAuth =  require('./googleOAuth')
    
    // resolve the promises for getting G files and folders
    const getGFilePaths = async () => {
      //update to use Promise.All()
      let gRootFolder = await getGfiles().then(result => {return result[2][0]['parents'][0]})
      let gFolders = await getGfiles().then(result => {return result[1]})
      let gFiles = await getGfiles().then(result => {return result[0]})
      // create the path files and create a new key with array of folder paths, returning an array of files with their folder paths
      return pathFiles = gFiles
                          .filter((file) => {return file.hasOwnProperty('parents')})
                          .map((file) => ({...file, path: makePathArray(gFolders, file['parents'][0], gRootFolder)}))
    }
    
    // recursive function to build an array of the file paths top -> bottom
    let makePathArray = (folders, fileParent, rootFolder) => {
      if(fileParent === rootFolder){return []}
      else {
        let filteredFolders = folders.filter((f) => {return f.id === fileParent})
        if(filteredFolders.length >= 1 && filteredFolders[0].hasOwnProperty('parents')) {
          let path = makePathArray(folders, filteredFolders[0]['parents'][0])
          path.push(filteredFolders[0]['name'])
          return path
        }
        else {return []}
      }
    }
    
    // get meta-data list of files from gDrive, with query parameters
    const getGfiles = () => {
      try {
        let getRootFolder = getGdriveList({corpora: 'user', includeItemsFromAllDrives: false,
        fields: 'files(name, parents)', 
        q: "'root' in parents and trashed = false and mimeType = 'application/vnd.google-apps.folder'"})
      
        let getFolders = getGdriveList({corpora: 'user', includeItemsFromAllDrives: false,
        fields: 'files(id,name,parents), nextPageToken', 
        q: "trashed = false and mimeType = 'application/vnd.google-apps.folder'"})
      
        let getFiles = getGdriveList({corpora: 'user', includeItemsFromAllDrives: false,
        fields: 'files(id,name,parents, mimeType, fullFileExtension, webContentLink, exportLinks, modifiedTime), nextPageToken', 
        q: "trashed = false and mimeType != 'application/vnd.google-apps.folder'"})
      
        return Promise.all([getFiles, getFolders, getRootFolder])
      }
      catch(error) {
        return `Error in retriving a file reponse from Google Drive: ${error}`
      }
    }
    
    // make call out gDrive to get meta-data files. Code adds all files in a single array which are returned in pages
    const getGdriveList = async (params) => {
      const gKeys = await gOAuth.get()
      const drive = google.drive({version: 'v3', auth: gKeys})
      let list = []
      let nextPgToken
      do {
        let res = await drive.files.list(params)
        list.push(...res.data.files)
        nextPgToken = res.data.nextPageToken
        params.pageToken = nextPgToken
      }
      while (nextPgToken)
      return list
    }

提交回复
热议问题