Skip to content

Instantly share code, notes, and snippets.

@Yama-to
Last active October 4, 2020 03:13
Show Gist options
  • Save Yama-to/87b8ff6709f51f5a2d5d148e540f3e38 to your computer and use it in GitHub Desktop.
Save Yama-to/87b8ff6709f51f5a2d5d148e540f3e38 to your computer and use it in GitHub Desktop.
RubyとPythonでGoogle APIを叩いてみた − データベースをSpreadsheetにしてGoogle Driveで管理する ref: http://qiita.com/Yama-to/items/74273213d5d89db7eb37
require 'google/apis/drive_v3'
require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'fileutils'
credentials_dir = File.join(Dir.home, '.credentials')
CLIENT_SECRETS_PATH = File.join(credentials_dir, 'client_secret.json')
CREDENTIALS_PATH = File.join(credentials_dir, 'sampleApp.yaml')
OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
APPLICATION_NAME = 'sampleApp'
SCOPE = Google::Apis::DriveV3::AUTH_DRIVE
class DriveUploader
# アップロードしたいCSVファイルが入っているフォルダへのパスを定義
FILE_DIR = 'out/'
# ファイルを保管しておきたいGoogle Drive上のフォルダのID等を定義
# 詳しくは下でまとめて説明
FOLDER_ID = '<Your Folder ID>'
MASTER_FILE_ID = '<Your Master FIle ID>'
MASTER_FOLDER_ID = '<Your Master Folder ID>'
def initialize
# APIインスタンスを生成
@@drive = Google::Apis::DriveV3
@@service = @@drive::DriveService.new
@@service.client_options.application_name = APPLICATION_NAME
@@service.authorization = authorize
end
def authorize
FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))
client_id = Google::Auth::ClientId.from_file(CLIENT_SECRETS_PATH)
token_store = Google::Auth::Stores::FileTokenStore.new(file: CREDENTIALS_PATH)
authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
user_id = 'default'
credentials = authorizer.get_credentials(user_id)
if credentials.nil?
url = authorizer.get_authorization_url(base_url: OOB_URI)
puts "Open the following URL in the browser and enter the " +
"resulting code after authorization"
puts url
code = gets
credentials = authorizer.get_and_store_credentials_from_code(user_id: user_id, code: code, base_url: OOB_URI)
end
credentials
end
def upload_csvs
##
# 実際にファイルをアップロードするメソッド
# 指定フォルダに入っている"~~.csv"という名前のファイルを全てアップロードする
# アップロードすべきファイルを探す
file_path = File.join(FILE_DIR, '*.csv')
files = Dir.glob(file_path)
abort('No files to upload.') if files.empty?
# アップロードタスクを全ての該当ファイルに対して繰り返す
counter = 0
files.each.with_index(1) do |a_file, i|
# ファイルの名前を"MMDD_FileName"というフォーマットに変換
file_name = Date.today.strftime('%m%d') + a_file.gsub(/out\/\d{4}-\d{2}-\d{2}/,'').gsub('.csv','')
puts "\nUploading[#{i}/#{files.count}]: #{file_name}"
# アップロードする先を定義
file_metadata = @@drive::File.new(
name: file_name,
mime_type: 'application/vnd.google-apps.spreadsheet',
parents: [FOLDER_ID]
)
# Goodle Drive上の指定のフォルダに変換済みファイルをアップロードする
file = @@service.create_file(file_metadata, upload_source: a_file, content_type: 'text/csv', fields: 'id')
file_id = file.id
puts "Successfully uploaded as:\nhttps://docs.google.com/spreadsheets/d/#{file_id}\n"
counter += 1
end
# 結果を出力
puts "\n\nTotal: #{counter.to_s} Files Uploaded\n"
end
def copy_master
##
#アップロードと同時にGoogle Drive上でコピーしておきたい日報等マスターファイルをコピー
#マスターファイルは既に定数として冒頭で定義してある通り
master_file_metadata = @@drive::File.new(
name: "#{Date.today.strftime('%m%d')}_Dashboard",
parents: [MASTER_FOLDER_ID]
)
master_file = @@service.copy_file(MASTER_FILE_ID, master_file_metadata)
puts "\nSuccessfully created as: #{master_file.name}\nhttps://docs.google.com/spreadsheets/d/#{master_file.id}"
end
end
# 本スクリプトをターミナルから [./uploader.rb] というコマンドで実行するための記述
if __FILE__ == $0
puts "Start uploading reports to Drive..."
DriveUploader.new.upload_csvs
puts "Copying master file in Drive..."
DriveUploader.new.copy_master
end
import httplib2
import os
import sys
import time
import glob
from apiclient import discovery
import oauth2client
from oauth2client import client
from oauth2client import tools
from apiclient.http import MediaFileUpload
CREDENTIAL_DIR = os.path.join(os.path.expanduser('~'), '.credentials')
CLIENT_SECRET_FILE = os.path.join(CREDENTIAL_DIR, 'client_secret.json')
CREDENTIAL_PATH = os.path.join(CREDENTIAL_DIR, 'piwikReport.json')
APPLICATION_NAME = 'piwikReport'
SCOPES = 'https://www.googleapis.com/auth/drive'
# アップロードしたいCSVファイルを保管しているフォルダまでのパスを定義
FILE_DIR = 'out/'
# ファイルを保管しておきたいGoogle Drive上のフォルダのID等を定義
# 詳しくは下でまとめて説明
FOLDER_ID = '<Your Folder ID>'
MASTER_FILE_ID = '<Your Master FIle ID>'
MASTER_FOLDER_ID = '<Your Master Folder ID>'
class DriveUploader(object):
def __init__(self):
"""
既にダウンロードして保存してある認証情報を使用して認証
"""
self.credentials = self.get_credentials()
self.http = self.credentials.authorize(httplib2.Http())
self.service = discovery.build('drive', 'v3', http=self.http)
def get_credentials(self):
"""
既にAPI認証が済んでいないかどうか確認
"""
if not os.path.exists(CREDENTIAL_DIR):
os.makedirs(CREDENTIAL_DIR)
store = oauth2client.file.Storage(CREDENTIAL_PATH)
credentials = store.get()
if not credentials or credentials.invalid:
flags = tools.argparser.parse_args(args=[])
flow = client.flow_from_clientsecrets(CLIENT_SECRET_FILE, SCOPES)
flow.user_agent = APPLICATION_NAME
if flags:
credentials = tools.run_flow(flow, store, flags)
else:
# Python2.6を使用しているユーザーのための記述
credentials = tools.run(flow, store)
print('Storing credentials to' + CREDENTIAL_PATH)
return credentials
def upload_csvs(self):
"""
実際にファイルをアップロードするメソッド
指定フォルダに入っている"~~.csv"という名前のファイルを全てアップロードする
"""
# アップロードするファイルを検索
file_path = os.path.join(FILE_DIR, '*.csv')
files = glob.glob(file_path)
if not files:
print('No files to upload.')
sys.exit()
# 該当のファイル全てに対しファイル名を変更してアップロードするタスクを繰り返す
counter = 1
for a_file in files:
# ファイルの名前を"MMDD_FileName"というフォーマットに変換
file_name = time.strftime('%m%d') + a_file.replace('out/','_').replace('.csv','')
print('>>>\nUploading[' + str(counter) + '/' + str(len(files)) + ']: ' + file_name)
# アップロードする先を確定
file_metadata = {
'name' : file_name,
'mimeType' : 'application/vnd.google-apps.spreadsheet',
'parents' : [FOLDER_ID]
}
# 既に定義済みのGoogle Driveフォルダへスプレッドシートの形式に変換したCSVデータをアップロード
media = MediaFileUpload(a_file, mimetype='text/csv', resumable=True)
file = self.service.files().create(body=file_metadata, media_body=media, fields='id').execute()
file_id = file.get('id')
print('Successfully uploaded as:\nhttps://docs.google.com/spreadsheets/d/' + file_id)
counter += 1
# 結果を出力
print('--------------\nTotal: '+ str(counter - 1) + ' Files Uploaded')
def copy_master(self):
"""
アップロードと同時にGoogle Drive上でコピーしておきたい日報等マスターファイルをコピー
マスターファイルは既に定数として冒頭で定義してある通り
"""
master_file_metadata = {
'name' : (time.strftime('%m%d') + '_PiwikReport'),
'parents' : [MASTER_FOLDER_ID]
}
master_file = self.service.files().copy(fileId=MASTER_FILE_ID, body=master_file_metadata, fields='id, name').execute()
print('Successfully created as: ' + master_file.get('name') + '\nhttps://docs.google.com/spreadsheets/d/' + master_file.get('id'))
# 本スクリプトをターミナルから [python3 uploader.py] というコマンドで実行するための記述
if __name__ == "__main__":
DriveUploader().copy_master()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment