我有一个python脚本,可以通过API创建Google云端硬盘文件并上传。我试图在Go中重写脚本,但API文档没有提供Go快速入门。这是python脚本:
#!/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\n")
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()
问题在于我无法弄清楚如何指定媒体类型。在Python中我使用了MediaFileUpload,但看起来Golang需要一个不同的方法。这就是我在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: \n%v\n", 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\n", 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)
}
}
有人可以提供一个创建文档并将文档上传到Google云端硬盘的工作示例吗?
参考链接位于:https://paste.fedoraproject.org/paste/JmElgduugSKLVSAYm1htGw
答案 0 :(得分:3)
这个示例脚本怎么样?此示例已修改为您脚本的main()
。使用此示例时,请将main()
替换为我的。{1}}。在Python脚本中,它将从CSV转换为电子表格并修改权限。所以它也为这个样本提供了相同的流程。
options
的{{1}}。Media(r io.Reader, options ...googleapi.MediaOption)
,请使用options
。googleapi.ContentType()
的{{1}}。file
,请使用Create(file *File)
。 file
。 Python的每个参数都与它们相同。&drive.File{}
&drive.Permission{}
此外,我从google-api-go-client的godoc和GitHub获得了此样本的信息。
这使用Quickstart。要使用此示例脚本,请执行步骤1和步骤2.
或者您的图书馆可能需要更新。
在此示例脚本中,它使用2017年9月13日的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\n", 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\n", pres.Type, pres.Role)
}
工作文件。