12 November 2018

(Python) PyDriveでGoogleドライブにファイル送信など

PyDriveライブラリを使って、Googleドライブにファイルをアップロードしたり、ファイル一覧を取得したりするサンプル スクリプト

PyDriveの説明は『PyDrive’s documentation』を参照。

スクリプトの全体構成

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
 
# スクリプトのあるディレクトリ以外から実行される場合(cron等での実行)、
# まず最初にカレントディレクトリを、スクリプトのあるディレクトリに変更する。
# (スクリプト自身のディレクトリに、client_secrets.json と settings.yaml が存在する必要あり)
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
 
# Googleドライブに接続
gauth = GoogleAuth()
gauth.CommandLineAuth()
drive = GoogleDrive(gauth)
 
# ***** 以下の説明では、この部分のみ処理ごとに記述 ***** 
# ルートフォルダにテキストファイルを作成
file = drive.CreateFile({'title' : '新規テキストファイル.txt'})
file.SetContentString("Hello World !\n")
file.Upload()

ルートフォルダにテキストファイルを新規作成

ルートフォルダを「明示」して、ファイルを作成する場合

file = drive.CreateFile({'title' : '新規テキストファイル2.txt', 'parents' : 'root'})
file.SetContentString("Hello World !\n")
file.Upload()

特定フォルダにテキストファイルを新規作成

フォルダは、「フォルダ名」ではなく「ID」を指定する。IDはGoogleドキュメントをWebブラウザで表示している時の、URLの末尾文字列。

file = drive.CreateFile({'title' : '新規テキストファイル3.txt',
            'parents' : [{'id' : '2_ic2bQ8m5H5ABjC_IEAArrrYGGKsJX36'}]})
file.SetContentString("Hello World !\n")
file.Upload()

特定フォルダにフォルダを新規作成

file = drive.CreateFile({'title' : '新規フォルダ',
            'parents' : [{'id' : '2_ic2bQ8m5H5ABjC_IEAArrrYGGKsJX36'}],
            'mimeType': 'application/vnd.google-apps.folder'})
file.Upload()

画像ファイルのアップロード

下の例では、ルートフォルダにアップロードされる

file = drive.CreateFile({'title' : '新規画像ファイル.jpg',
            'mimeType' : 'image/jpeg'})
file.SetContentFile('local-file.jpg')
file.Upload()

ファイル、フォルダ一覧の表示

PyDrive経由で作成したファイル、フォルダ一覧のみが表示される。parentのidを指定しない場合は、ルートフォルダ以下、全てのフォルダに存在するファイル等の一覧が得られる

file_list = drive.ListFile({'q': "trashed=false"}).GetList()
 
for file1 in file_list:
    print('title: %s, id: %s' % (file1['title'], file1['id']))

クエリ文に 「親フォルダ」、「ファイルのmimeType」の検索条件を付ける場合。クエリ文はGoogle Drive APIの『Search for Files and Team Drives』に説明が記載されている。 また、最大検索数などの検索条件は 『Files: list リファレンス』に掲載されている。

drive_folder_id = '2_ic2bQ8m5H5ABjC_IEAArrrYGGKsJX36'
 
file_list = drive.ListFile({'q': "'%s' in parents and trashed=false and mimeType='text/plain'" %
                drive_folder_id, 'maxResults' : 100}).GetList()
 
for file1 in file_list:
    print('title: %s, id: %s' % (file1['title'], file1['id']))

ファイルのmimeTypeには、 text/plain image/jpeg などのほか、Googleドライブ特有のフォルダを示す application/vnd.google-apps.folder などがある。

また、ファイル名の一部に「◯◯」という文字列が含まれているものを探す場合は、 title contains '◯◯' というクエリ条件をつければ良い。

なお、containsで指定する条件は、ファイル名の先頭または末尾からしかマッチングしないようだ。(バグ?)

file_list = drive.ListFile({trashed=false and title contains '◯◯'"}).GetList()
 
for file1 in file_list:
    print('title: %s, id: %s' % (file1['title'], file1['id']))

指定日時以降のファイルを抽出して表示するには…

file_list = drive.ListFile({trashed=false and modifiedDate > '2018-11-12'"}).GetList()
 
for file1 in file_list:
    print('title: %s, id: %s' % (file1['title'], file1['id']))

特定のフォルダ内のファイルで、今日から10日以内という条件で表示するなら…

drive_folder_id = '2_ic2bQ8m5H5ABjC_IEAArrrYGGKsJX36'
date_period = (datetime.date.today() - datetime.timedelta(days=10)).strftime("%Y-%m-%d")
 
file_list = drive.ListFile({'%s' in parents and trashed=false and modifiedDate > '%s'" % 
                (drive_folder_id, date_period) }).GetList()
 
for file1 in file_list:
    print('title: %s, id: %s' % (file1['title'], file1['id']))

ファイル属性を詳しく出力する場合は

print('検索条件に一致するファイル/フォルダ数 = ' + str(len(file_list)))
 
for file1 in file_list:
    print('title : ' + file1['title'] + "\n" +
        'id : ' + file1['id'] + "\n" +
        'mimeType : ' + file1['mimeType'] + "\n" +
        'fileSize : ' + (file1['fileSize'] if 'fileSize' in file1.keys() else '---') + " Bytes\n" +
        'createdDate : ' + file1['createdDate'] + "\n" +
        'modifiedDate : ' + file1['modifiedDate'] + "\n" +
        'modifiedByMeDate : ' + file1['modifiedByMeDate'] + "\n" +
        'trashed : ' + ('True' if file1['labels']['trashed'] == True else 'False') + "\n" +
        'hidden : ' + ('True' if file1['labels']['hidden'] == True else 'False') + "\n"
        )

全ての属性を垂れ流して表示する場合

for file1 in file_list:
    print(file1.items())
    print("\n")

GetListの検索結果をソートして出力するには

Google Drive APIs REST v2 - Files: list の orderBy を用いる。

v3 ではなく v2 の属性を使うこと

drive_folder_id = '2_ic2bQ8m5H5ABjC_IEAArrrYGGKsJX36'
 
file_list = drive.ListFile({'q': "'%s' in parents and trashed=false and mimeType='text/plain'" %
                drive_folder_id,
                'maxResults' : 100, 'orderBy' : 'folder,modifiedDate desc'}).GetList()
 
for file1 in file_list:
    print('title: %s, id: %s' % (file1['title'], file1['id']))

orderByには複数のソート条件を列挙でき、createdDate = 作成日時、modifiedDate = 最終の編集日時、lastViewedByMeDate = 最終閲覧の日時、folder = フォルダ名、title = ファイル名 などが指定できる。

逆順にソートする場合は desc をつければよい


条件にあったファイルを削除する

指定日以降のファイルを全て削除する場合

file_list = drive.ListFile({trashed=false and modifiedDate > '2018-11-12"}).GetList()
 
for file1 in file_list:
    file1.Delete()

削除はDelete()を、ゴミ箱に入れるのはTrash()を使う。