Google Drive(docs)からrubyでファイルをコピーする方法メモ。
Google Drive(docs)からrubyでファイルをコピーする方法
まずはじめに、oauth認証、client_id、client_secretの扱い方についてはこのページをご参照ください。
Google Drive(docs)からrubyでファイル一覧を取得する方法
上記のページで紹介している認証さえ出来れば後は簡単です!
Google Drive(docs)からファイルをコピーするrubyコード
gemはgoogle-api-ruby-clientを使うのが現状ベストっぽいです。
google-api-ruby-clientの作者(google)が、Google Driveにファイルを新規にアップロードするサンプルを公開してくれています。
github google-api-ruby-client-samples drive.rb
ただし上記のサンプルコードだけではバグが残っています。そのバグを手直しして、ファイル新規アップロードではなく、特定のファイルをコピーするコードは下記の通りです。
# -*- coding: utf-8 -*-
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'google/api_client/auth/installed_app'
require 'logger'
API_VERSION = 'v2'
CACHED_API_FILE = "drive-#{API_VERSION}.cache"
CREDENTIAL_STORE_FILE = "#{$0}-oauth2.json"
# gemにバグがあるらしく、暫定的なコードとしてこの変換がおすすめされている。
# この処理がないと、refresh_tokenを使ったtoken再取得に失敗する。
# https://github.com/google/google-api-ruby-client/issues/90
def file_format_bug_fix(credential_store_file)
return if !File.exists?(credential_store_file)
temp = nil
File.open(credential_store_file, "r") do |f|
temp = JSON.load(f)
if temp["authorization_uri"].class != String
temp["authorization_uri"] =
"https://accounts.google.com/o/oauth2/auth"
end
if temp["token_credential_uri"].class != String
temp["token_credential_uri"] =
"https://accounts.google.com/o/oauth2/token"
end
end
File.open(credential_store_file, "w") do |f|
f.write(temp.to_json)
end
end
def setup()
log_file = File.open('log/drive.log', 'a+')
log_file.sync = true
logger = Logger.new(log_file)
logger.level = Logger::DEBUG
client = Google::APIClient.new(:application_name => 'Ruby Drive sample',
:application_version => '1.0.0')
file_storage = Google::APIClient::FileStorage.new(CREDENTIAL_STORE_FILE)
if file_storage.authorization.nil?
client_secrets = Google::APIClient::ClientSecrets.load
flow = Google::APIClient::InstalledAppFlow.new(
:client_id => client_secrets.client_id,
:client_secret => client_secrets.client_secret,
:scope => ['https://www.googleapis.com/auth/drive']
)
client.authorization = flow.authorize(file_storage)
else
client.authorization = file_storage.authorization
end
drive = nil
if File.exists? CACHED_API_FILE
File.open(CACHED_API_FILE) do |file|
drive = Marshal.load(file)
end
else
drive = client.discovered_api('drive', API_VERSION)
File.open(CACHED_API_FILE, 'w') do |file|
Marshal.dump(drive, file)
end
end
return client, drive
end
# file_idをtitleという名前でfolder_idにコピーする
def copy_file(client, drive, file_id, folder_id)
file = drive.files.insert.request_schema.new({
'title' => 'new_title',
'parents' => [{:id => folder_id}]
})
result = client.execute(
:api_method => drive.files.copy,
:body_object => file,
:parameters => {
'fileId' => file_id,
'alt' => 'json'})
#jj result.data.to_hash
result.data
end
if __FILE__ == $0
file_format_bug_fix(CREDENTIAL_STORE_FILE)
client, drive = setup()
file = copy_file(client, drive, 'aaabbbccc', '111222333')
end
上記のrubyコードでは、「file_idで指定したファイルを、folder_idで指定したフォルダに、titleというファイル名でコピー」という処理をしています。APIの仕様は公式リファレンスをご参照ください。
その他注意事項
上記のrubyコードを実行する際は、client_secrets.jsonをrubyコードと同じディレクトリに置いておくと、client_id、client_secretが自動で読み込まれます。
「Unable to find a browser command. ~ Launchy::CommandNotFoundError」の対策
上記のrubyコードをlinux上で実行する際は、まずlocalhost(macとか)で実行して、drive.rb-oauth2.jsonを生成しておき、drive.rb-oauth2.jsonをlinux上のrubyコードと同じディレクトリに置いておきましょう。初回のみブラウザでの認証が必須なため、localhostで先にdrive.rb-oauth2.jsonを生成しておく必要があります。
ご意見、ご質問
分からない点等は@ts_3156までお気軽にご質問ください(^^)
参考リンク
Google Developers API Reference
Google Drive(docs)からrubyでファイル一覧を取得する方法
Google Drive(docs)からrubyでファイルを取得する方法
