James Gan
James Gan

Reputation: 7126

What's the right way to find files by "full path" in Google Drive API v2

dear all

I'm trying to find a list of documents by "full path". And after reading the API reference, it seems to be a complex task. Assume my path is something like /path0/path1/path2/...

  1. List children of root folder and find all children with name equals "path0" and put them to a list "result0"
  2. Find all children of items in "result0" with name equals "path1" and put them to a list "result1"
  3. Find all children of items in "result1" with name equals "path2" and ...

Above approach seems very low efficient cause it needs multiple interactions between my application and Drive. I understand Google Drive allows multiple files share the same file name even in the same folder. It will be handy if I can do something like:

listDocByFullPath("path0/path1/path2")

Is this possible with current version of Google Drive SDK? If it's not there yet, I was wondering if there is a simpler way than what I listed here.

BTW, as my application is purely a back-end service, it's not possible to use file picker provided by Google.

Cheers.

Upvotes: 28

Views: 12469

Answers (4)

Dave Ranjan
Dave Ranjan

Reputation: 2984

@Barcu Dogan is correct,, that's the only way to find full path, here is the implementation:

//BeanConfig.java
   @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    public Drive drive() throws GeneralSecurityException, IOException {
        Drive drive = new Drive.Builder(GoogleNetHttpTransport.newTrustedTransport(), JSON_FACTORY, getCredentials())
                .setApplicationName(APPLICATION_NAME)
                .build();

        return drive;
    }

    private static HttpRequestInitializer getCredentials() throws IOException {
        // Load client credentials from path
        GoogleCredentials credential = GoogleCredentials.fromStream(new FileInputStream(CREDENTIALS_FILE_PATH))
                .createScoped(DriveScopes.all());

        return new HttpCredentialsAdapter(credential);
    }


//FileHelper.java
//pass folderId or fileId
public String getCompletePath(Drive drive, String folderId) {
        String path = "";
        try {
            File files = drive.files()
                    .get(folderId).setFields("id,name,parents")
                    .execute();
            return recursivePath(drive, files, path);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return path;
    }

public String recursivePath(Drive drive, File currentFolder, String path) throws IOException {
        if (currentFolder == null || currentFolder.getParents() == null || currentFolder.getParents().isEmpty())
            return path;
        if (!path.equalsIgnoreCase("")) {
            path = currentFolder.getName() + "/" + path;
        } else {
            path = currentFolder.getName();
        }
        File parentFolder = drive.files().get(currentFolder.getParents().get(0)).setFields("id,name,parents").execute();
        return recursivePath(drive, parentFolder, path);
    }

Upvotes: 0

arunram
arunram

Reputation: 633

  1. Search / list with the param q set to name= and include fields param with "files(mimeType,id,name,parents)"
  2. If there is only one search result, return this file
  3. Else if there are multiple files, get the ID in parent and use file's get API with that ID and check if the name matches the last fragment in the path. If only one of the parent Ids match select that option else pick the matching parents and get to check the next parent element in the path

Essentially check bottom up

Upvotes: 1

Rehan
Rehan

Reputation: 1339

The biggest problem is that a path does not uniquely identify the file or folder! For example, in the web UI, you can make 2 folders with the same name as children of the same folder. i.e. you can make a tree that looks like: root |-somefolder |-somefolder

Upvotes: 7

Burcu Dogan
Burcu Dogan

Reputation: 9213

Unlike conventional file systems, a file could be under multiple folders on Drive. Folders are pretty much similar what labels are. Therefore, conventional paths dont always work within our abstraction. I'd suggest you to follow the logic below:

  1. List files with q = 'root' in parents and title = 'path0' and mimeType = 'application/vnd.google-apps.folder' and pick the first result.
  2. If there is a matching result, get the folder's id and perform another listing with '<id of path0>' in parents and title = 'path1' and mimeType='application/vnd.google-apps.folder' and pick the first result.
  3. Keep going until you reach to your target folder.

Upvotes: 20

Related Questions