Tuesday, August 19, 2014

Google Drive API - searching

Part1

Search for an item by name

List files

Google Drive API is a REST API. One have a resources which can be created, changed or removed.
In Google Drive both files and directories are represented as a file. To look for a file with a specific name we have to use List method of a resource File.
Documentation: Files.List
When programming in Go, it's worth to look at implementation: Drive API in Go
One is interested in FilesService and search for a method List on it. The method returns FilesListCall which have methods allowing to set different query parameters.
Simple code getting all files:
func GetAllFiles(srv *drive.Service) ([]*drive.File, error) {
  return d.Files.List().Do()
}
According to the documentation, the List method by default returns all files on Drive limited by a maxResults parameter. One can change the limit by calling: d.Files.List().MaxResults(10). The default value is 100, and possible values are between 0 and 1000. If there are more files to list, the method returns a valid PageToken string in reponse which can be used in a following requests.
One can copy from documentation an example code in Go which handles PageToken:
// AllFiles fetches and displays all files
func AllFiles(d *drive.Service) ([]*drive.File, error) {
  var fs []*drive.File
  pageToken := ""
  for {
    q := d.Files.List()
    // If we have a pageToken set, apply it to the query
    if pageToken != "" {
      q = q.PageToken(pageToken)
    }
    r, err := q.Do()
    if err != nil {
      fmt.Printf("An error occurred: %v\n", err)
      return fs, err
    }
    fs = append(fs, r.Items...)
    pageToken = r.NextPageToken
    if pageToken == "" {
      break
    }
  }
  return fs, nil
}
Few words about results. The API returns []*drive.File. It's worth to take a look at a documentation: File and a code: type File struct in API source code.
The final code looks like: gist.github.com/orian/6a0d7883ca3678cb30ea

Search for a file with a specific name

Files don't have a name per se, the name shown in a drive.google.com is an attribute title of a resource File: File reference.
To search only files with a specific name we need to use q parameter. Go API allows to do that through Q(string) method. Example code below:
func FindFile(srv *drive.Service, name string) ([]*drive.File, error) {
  q := fmt.Sprintf("title = '%s'", name)
  return Files.List().Q(q).Do()
}

Search for a directory

The directory is a Google drive file with a special mimetype: 'application/vnd.google-apps.folder'. To search for a directory with a specific name we need to extend the previous code and a query parameter by "mimeType = 'application/vnd.google-apps.folder'".
func FindDir(srv *drive.Service, name string) ([]*drive.File, error) {
  q := fmt.Sprintf("mimeType = 'application/vnd.google-apps.folder' and title = '%s'", name)
  return Files.List().Q(q).Do()
}

Search for a directory knowing its parent id

If a name is not an identifier of file on Drive than what? FileId is an unique id given to each file on Google Drive. It's available as Id field of struct drive.File. If we look at search documentation: search parameters we can find parents property on which we can use operator in. E.g. when we have a folder id 1234 we can require a file to be in folder by writing '1234 in parents' as query.
func FindSubDir(srv *drive.Service, name, parentId string) ([]*drive.File, error) {
  subq := []string{
      "mimeType = 'application/vnd.google-apps.folder'", 
      fmt.Sprintf("title = '%s'", name),
      fmt.Sprintf("'%s' in parents", parentId),
  }
  q := strings.Join(subq, " and ")
  return Files.List().Q(q).Do()
}

No comments:

Post a Comment