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 WPF动态创建页面内容
  • ¥15 如何对TBSS的结果进行统计学的分析已完成置换检验,如何在最终的TBSS输出结果提取除具体值及如何做进一步相关性分析
  • ¥15 SQL数据库操作问题
  • ¥100 关于lm339比较电路出现的问题
  • ¥15 Matlab安装yalmip和cplex功能安装失败
  • ¥15 加装宝马安卓中控改变开机画面
  • ¥15 STK安装问题问问大家,这种情况应该怎么办
  • ¥15 关于罗技鼠标宏lua文件的问题
  • ¥15 halcon ocr mlp 识别问题
  • ¥15 已知曲线满足正余弦函数,根据其峰值,还原出整条曲线