doubianxian6557 2017-09-21 02:48
浏览 203
已采纳

Google Drive API v3创建和上传文件

I have a python script that creates a Google Drive file via API and uploads it. I am trying to rewrite the script in Go but the API documentation does not provide a Go quickstart. Here is the python script:

#!/bin/python
from __future__ import print_function
import httplib2
import os

from apiclient import discovery
from oauth2client import client
from oauth2client import tools
from oauth2client.file import Storage
from apiclient.http import MediaFileUpload

try:
 import argparse
 parser = argparse.ArgumentParser(description='Ebay Google Drive Uploader')
 parser.add_argument('-r', metavar="rack",
  help="-r <rack>")
except ImportError:
 parser = None

try:
 args = parser.parse_args()
except:
 print (parser.error)
#print ("parser = ", parser)

if not args.r:
 print ("Please specify rack (-r rack)")
 exit
else:
 #print ("Processing ", args.r)
 sheet_name = args.r + ".csv"
 sheet_filename = '/tmp/' + args.r + '.csv'

# If modifying these scopes, delete your previously saved credentials
# at ~/.credentials/drive-python-quickstart.json
SCOPES = 'https://www.googleapis.com/auth/drive'
CLIENT_SECRET_FILE = 'client_secret.json'
APPLICATION_NAME = 'Ebay Google Drive Uploader - albraden@ebay.com'


def get_credentials():
 """Gets valid user credentials from storage.
 Returns:
  Credentials, the obtained credential.
 """
 home_dir = os.path.expanduser('~')
 credential_dir = os.path.join(home_dir, '.credentials')
 if not os.path.exists(credential_dir):
  os.makedirs(credential_dir)
 credential_path = os.path.join(credential_dir,
  'drive-python-quickstart.json')

 store = Storage(credential_path)
 credentials = store.get()
 if not credentials or credentials.invalid:
  print ("before flow
")
  flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
  print ("flow = ", flow)
  flow.user_agent = APPLICATION_NAME
  if parser:
   credentials = tools.run_flow(flow, store, parser)
  else: # Needed only for compatibility with Python 2.6
   credentials = tools.run(flow, store)
  print('Storing credentials to ' + credential_path)
 return credentials

def main():
 """Creates a spreadsheet using the Google Drive API
 """
 credentials = get_credentials()
 http = credentials.authorize(httplib2.Http())
 service = discovery.build('drive', 'v3', http=http)

 file_metadata = {
  'name' : sheet_name,
  'mimeType' : 'application/vnd.google-apps.spreadsheet'
 }
 media = MediaFileUpload(sheet_filename,
  mimetype='text/csv')
 results  = service.files().create(body=file_metadata,
                                   media_body=media,
                                   fields='id').execute()

 sheet_id = results["id"]
 print (sheet_id)
 #sheet_url = results["webViewLink"]
 #print ('sheet_url = ', sheet_url)
 def callback(request_id, response, exception):
  if exception:
   # Handle error
   print (exception)
  #else:
   #print ("Permission Id: %s" % response.get('id'))

 batch = service.new_batch_http_request(callback=callback)
 domain_permission = {
  'type': 'domain',
  'role': 'writer',
  'domain': 'ebay.com',
  'allowFileDiscovery': True
 }
 batch.add(service.permissions().create(
  fileId=sheet_id,
  body=domain_permission,
  fields='id',
 ))
 batch.execute()

if __name__ == '__main__':
    main()

The problem is that I can't figure out how to specify the media type. In Python I used MediaFileUpload but it looks like Golang requires a different method. Here's what I have in Go:

package main

import (
 "encoding/json"
 "fmt"
 "io/ioutil"
 "log"
 "net/http"
 "net/url"
 "os"
 "os/user"
 "path/filepath"

 "golang.org/x/net/context"
 "golang.org/x/oauth2"
 "golang.org/x/oauth2/google"
 "google.golang.org/api/drive/v3"
)

// getClient uses a Context and Config to retrieve a Token
// then generate a Client. It returns the generated Client.
func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
 cacheFile, err := tokenCacheFile()
 if err != nil {
  log.Fatalf("Unable to get path to cached credential file. %v", err)
 }
 tok, err := tokenFromFile(cacheFile)
 if err != nil {
  tok = getTokenFromWeb(config)
  saveToken(cacheFile, tok)
 }
 return config.Client(ctx, tok)
}

// getTokenFromWeb uses Config to request a Token.
// It returns the retrieved Token.
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
 authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
 fmt.Printf("Go to the following link in your browser then type the "+
  "authorization code: 
%v
", authURL)

 var code string
 if _, err := fmt.Scan(&code); err != nil {
  log.Fatalf("Unable to read authorization code %v", err)
 }

 tok, err := config.Exchange(oauth2.NoContext, code)
 if err != nil {
  log.Fatalf("Unable to retrieve token from web %v", err)
 }
 return tok
}

// tokenCacheFile generates credential file path/filename.
// It returns the generated credential path/filename.
func tokenCacheFile() (string, error) {
 usr, err := user.Current()
 if err != nil {
  return "", err
 }
 tokenCacheDir := filepath.Join(usr.HomeDir, ".credentials")
 os.MkdirAll(tokenCacheDir, 0700)
 return filepath.Join(tokenCacheDir,
  url.QueryEscape("drive-go-quickstart.json")), err
}

// tokenFromFile retrieves a Token from a given file path.
// It returns the retrieved Token and any read error encountered.
func tokenFromFile(file string) (*oauth2.Token, error) {
 f, err := os.Open(file)
 if err != nil {
  return nil, err
 }
 t := &oauth2.Token{}
 err = json.NewDecoder(f).Decode(t)
 defer f.Close()
 return t, err
}

// saveToken uses a file path to create a file and store the
// token in it.
func saveToken(file string, token *oauth2.Token) {
 fmt.Printf("Saving credential file to: %s
", file)
 f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
 if err != nil {
  log.Fatalf("Unable to cache oauth token: %v", err)
 }
 defer f.Close()
 json.NewEncoder(f).Encode(token)
}

func main() {
 ctx := context.Background()
 b, err := ioutil.ReadFile("/usr/local/lib/client_secret.json")
 if err != nil {
  log.Fatalf("Unable to read client secret file: %v", err)
 }

 // If modifying these scopes, delete your previously saved credentials
 // at ~/.credentials/drive-go-quickstart.json
 config, err := google.ConfigFromJSON(b, drive.DriveFileScope)
 if err != nil {
  log.Fatalf("Unable to parse client secret file to config: %v", err)
 }
 client := getClient(ctx, config)

 srv, err := drive.New(client)
 if err != nil {
  log.Fatalf("Unable to retrieve drive Client %v", err)
 }

 file_metadata := make(map[string]string)
 sheet_name := "SLC:SLC02:02-314:06:04.csv"
 sheet_filename := "/tmp/SLC:SLC02:02-314:06:04.csv"
 file_metadata["name"] = sheet_name
 file_metadata["mimeType"] = "application/vnd.google-apps.spreadsheet"
 media = MediaFileUpload(sheet_filename, mimetype="text/csv")


 r, err := srv.Files.Create(body=file_metadata,
                            media_body=media,
                            fields='id')
 if err != nil {
  log.Fatalf("Unable to create file: %v", err)
 }
}

Can someone provide a working example that creates and uploads a document to Google Drive?

Reference links are here: https://paste.fedoraproject.org/paste/JmElgduugSKLVSAYm1htGw

  • 写回答

1条回答 默认 最新

  • dpgua04022 2017-09-21 06:41
    关注

    How about this sample script? This sample was modified main() of your script. When you use this sample, please replace your main() to mine. In your Python script, it converts from CSV to Spreadsheet and modify the permissions. So also it gave the same flow to this sample.

    Important points :

    1. Give mimeType of file that it wants to upload to options of Media(r io.Reader, options ...googleapi.MediaOption).
    2. In order to give options, use googleapi.ContentType().
    3. Give mimeType of file that it wants to convert, when it uploads it to Google Drive, to file of Create(file *File).
    4. In order to give file, use &drive.File{}.
    5. For installing permissions, use &drive.Permission{}. Each parameter is the same to them for Python.

    Sample script :

    func main1() {
        ctx := context.Background()
        b, err := ioutil.ReadFile("/usr/local/lib/client_secret.json")
        if err != nil {
            log.Fatalf("Unable to read client secret file: %v", err)
        }
    
        // If modifying these scopes, delete your previously saved credentials
        // at ~/.credentials/drive-go-quickstart.json
        config, err := google.ConfigFromJSON(b, drive.DriveFileScope)
        if err != nil {
            log.Fatalf("Unable to parse client secret file to config: %v", err)
        }
        client := getClient(ctx, config)
    
        srv, err := drive.New(client)
        if err != nil {
            log.Fatalf("Unable to retrieve drive Client %v", err)
        }
    
        //  I modified below.
        sheet_name := "SLC:SLC02:02-314:06:04.csv"                     // File you want to upload on Google Drive
        sheet_filename := "/tmp/SLC:SLC02:02-314:06:04.csv"            // File you want to upload on your PC
        baseMimeType := "text/csv"                                     // mimeType of file you want to upload
        convertedMimeType := "application/vnd.google-apps.spreadsheet" // mimeType of file you want to convert on Google Drive
    
        file, err := os.Open(sheet_filename)
        if err != nil {
            log.Fatalf("Error: %v", err)
        }
        defer file.Close()
        f := &drive.File{
            Name:     sheet_name,
            MimeType: convertedMimeType,
        }
        res, err := srv.Files.Create(f).Media(file, googleapi.ContentType(baseMimeType)).Do()
        if err != nil {
            log.Fatalf("Error: %v", err)
        }
        fmt.Printf("%s, %s, %s
    ", res.Name, res.Id, res.MimeType)
    
        permissiondata := &drive.Permission{
            Type:               "domain",
            Role:               "writer",
            Domain:             "ebay.com",
            AllowFileDiscovery: true,
        }
        pres, err := srv.Permissions.Create(res.Id, permissiondata).Do()
        if err != nil {
            log.Fatalf("Error: %v", err)
        }
        fmt.Printf("%s, %s
    ", pres.Type, pres.Role)
    }
    

    Result :

    SLC:SLC02:02-314:06:04.csv, ### file ID on Google Drive ###, application/vnd.google-apps.spreadsheet
    domain, writer
    

    References :

    Also I got the infomation for this sample from godoc and GitHub of google-api-go-client.

    Edit :

    This uses Quickstart. In order to use this sample script, please do the Step 1 and Step 2.

    Or your library may be required to update.

    At this sample script, it works file using google-api-go-client/drive/v3/ of Sep 13, 2017.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器