在 google 驱动器上创建一个文件夹(如果不存在)并使用 Python 脚本将文件上传到该文件夹
Create a folder (if not exists) on google drive and upload a file to it using Python script
到目前为止,我可以将文件上传到文件夹(如果存在)。我想不出一种方法来创建一个。所以如果文件夹不存在,我的脚本就会死掉。
import sys
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
gpath = '2015'
fname = 'Open Drive Replacements 06_01_2015.xls'
gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)
file_list = drive.ListFile({'q': "'root' in parents and trashed=false"}).GetList()
for file1 in file_list:
if file1['title'] == gpath:
id = file1['id']
file1 = drive.CreateFile({'title': fname, "parents": [{"kind": "drive#fileLink","id": id}]})
file1.SetContentFile(fname)
file1.Upload()
如果gpath不存在,能否帮我修改上面的代码创建文件夹?
根据documentation,应该是
file1 = drive.CreateFile({'title': fname,
"parents": [{"id": id}],
"mimeType": "application/vnd.google-apps.folder"})
更新:截至 2020 年 4 月,documentation (v3) 已使用 API 文档更新并显示:
folder_id = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E'
file_metadata = {
'name': 'photo.jpg',
'parents': [folder_id]
}
media = MediaFileUpload('files/photo.jpg',
mimetype='image/jpeg',
resumable=True)
file = drive_service.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
print 'File ID: %s' % file.get('id')
上面的答案对我没有用,这个确实有用。它returns新建文件夹的id
def createRemoteFolder(folderName, parentID ):
folderlist = (drive.ListFile ({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList())
titlelist = [x['title'] for x in folderlist]
if folderName in titlelist:
for item in folderlist:
if item['title']==folderName:
return item['id']
file_metadata = {
'title': folderName,
'mimeType': 'application/vnd.google-apps.folder',
'parents': [{"id": parentID}]
}
file0 = drive.CreateFile(file_metadata)
file0.Upload()
return file0['id']
我遇到了同样的问题,偶然发现了这个问题。这是我想出的代码:
import os
from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDriv
class GoogleDriveConnection:
_gauth = None
_drive = None
@staticmethod
def get() -> GoogleDrive:
"""
This will return a valid google drive connection
:return: A valid GoogleDrive connection
"""
if GoogleDriveConnection._gauth is None or GoogleDriveConnection._drive == None:
GoogleDriveConnection._gauth = GoogleAuth()
GoogleDriveConnection._gauth.LoadCredentialsFile(os.path.join(os.path.dirname(__file__), "mycredentials.txt")) # this assume you have saved your credentials, like this: gauth.SaveCredentialsFile("mycredentials.txt")
GoogleDriveConnection._drive = GoogleDrive(GoogleDriveConnection._gauth)
return GoogleDriveConnection._drive
@staticmethod
def upload_image(image_path: str, folder_path: str) -> str:
"""
Uploads an image to the google drive, and returns the https path to it
:param image_path: Path to the image, has to end in an image type else the type won't be guessed correctly
:param folder_path: The folder path it should have in the google drive (to structure the data there)
:return: The https path to the uploaded image file, will be empty if the image_path is invalid
"""
if os.path.exists(image_path):
google_drive = GoogleDriveConnection.get()
image = google_drive.CreateFile()
image.SetContentFile(image_path) # load local file data into the File instance
# to remove the path from the filename
image["title"] = os.path.basename(image_path)
if folder_path:
parent_id = GoogleDriveConnection.get_folder_id(folder_path)
image["parents"] = [{"id": parent_id}]
image.Upload() # creates a file in your drive with the name
return "https://drive.google.com/uc?id=" + str(image['id'])
return ""
@staticmethod
def get_folder_id(folder_path: str, element_index=0, last_parent=None) -> str:
"""
Gets the id of the given folder path, this function will create the folders, if they do not exist, so it will
always return a valid id, the folder_path elements can be separated like normals via a slash.
:param folder_path: Given folder path
:param element_index: Element index needed for recursive creation of the element
:param last_parent: Last parent only needed for recursive creation of the folder hierarchy
:return: The id to the last folder in the path
"""
folder_path_elements = folder_path.split("/")
if len(folder_path_elements) == element_index:
return last_parent
folder_list = GoogleDriveConnection.get().ListFile({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList()
current_folder_name = folder_path_elements[element_index]
for item in folder_list:
if item['title'] == current_folder_name and item["parents"][0] == last_parent:
return GoogleDriveConnection.get_folder_id(folder_path, element_index + 1, item['id'])
# not in the list -> folder has to be created
file_metadata = {'title': current_folder_name, 'mimeType': 'application/vnd.google-apps.folder'}
if last_parent is not None:
file_metadata['parents'] = [{"id": last_parent}]
new_folder = GoogleDriveConnection.get().CreateFile(file_metadata)
new_folder.Upload()
return GoogleDriveConnection.get_folder_id(folder_path, element_index + 1, new_folder["id"])
这使您能够将图像加载到 Google 驱动器,如果您调用 get_folder_id
,它将为您提供该文件夹的 ID,如果该文件夹不存在,它将被创建。
到目前为止,我可以将文件上传到文件夹(如果存在)。我想不出一种方法来创建一个。所以如果文件夹不存在,我的脚本就会死掉。
import sys
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
gpath = '2015'
fname = 'Open Drive Replacements 06_01_2015.xls'
gauth = GoogleAuth()
gauth.LocalWebserverAuth()
drive = GoogleDrive(gauth)
file_list = drive.ListFile({'q': "'root' in parents and trashed=false"}).GetList()
for file1 in file_list:
if file1['title'] == gpath:
id = file1['id']
file1 = drive.CreateFile({'title': fname, "parents": [{"kind": "drive#fileLink","id": id}]})
file1.SetContentFile(fname)
file1.Upload()
如果gpath不存在,能否帮我修改上面的代码创建文件夹?
根据documentation,应该是
file1 = drive.CreateFile({'title': fname,
"parents": [{"id": id}],
"mimeType": "application/vnd.google-apps.folder"})
更新:截至 2020 年 4 月,documentation (v3) 已使用 API 文档更新并显示:
folder_id = '0BwwA4oUTeiV1TGRPeTVjaWRDY1E'
file_metadata = {
'name': 'photo.jpg',
'parents': [folder_id]
}
media = MediaFileUpload('files/photo.jpg',
mimetype='image/jpeg',
resumable=True)
file = drive_service.files().create(body=file_metadata,
media_body=media,
fields='id').execute()
print 'File ID: %s' % file.get('id')
上面的答案对我没有用,这个确实有用。它returns新建文件夹的id
def createRemoteFolder(folderName, parentID ):
folderlist = (drive.ListFile ({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList())
titlelist = [x['title'] for x in folderlist]
if folderName in titlelist:
for item in folderlist:
if item['title']==folderName:
return item['id']
file_metadata = {
'title': folderName,
'mimeType': 'application/vnd.google-apps.folder',
'parents': [{"id": parentID}]
}
file0 = drive.CreateFile(file_metadata)
file0.Upload()
return file0['id']
我遇到了同样的问题,偶然发现了这个问题。这是我想出的代码:
import os
from pydrive2.auth import GoogleAuth
from pydrive2.drive import GoogleDriv
class GoogleDriveConnection:
_gauth = None
_drive = None
@staticmethod
def get() -> GoogleDrive:
"""
This will return a valid google drive connection
:return: A valid GoogleDrive connection
"""
if GoogleDriveConnection._gauth is None or GoogleDriveConnection._drive == None:
GoogleDriveConnection._gauth = GoogleAuth()
GoogleDriveConnection._gauth.LoadCredentialsFile(os.path.join(os.path.dirname(__file__), "mycredentials.txt")) # this assume you have saved your credentials, like this: gauth.SaveCredentialsFile("mycredentials.txt")
GoogleDriveConnection._drive = GoogleDrive(GoogleDriveConnection._gauth)
return GoogleDriveConnection._drive
@staticmethod
def upload_image(image_path: str, folder_path: str) -> str:
"""
Uploads an image to the google drive, and returns the https path to it
:param image_path: Path to the image, has to end in an image type else the type won't be guessed correctly
:param folder_path: The folder path it should have in the google drive (to structure the data there)
:return: The https path to the uploaded image file, will be empty if the image_path is invalid
"""
if os.path.exists(image_path):
google_drive = GoogleDriveConnection.get()
image = google_drive.CreateFile()
image.SetContentFile(image_path) # load local file data into the File instance
# to remove the path from the filename
image["title"] = os.path.basename(image_path)
if folder_path:
parent_id = GoogleDriveConnection.get_folder_id(folder_path)
image["parents"] = [{"id": parent_id}]
image.Upload() # creates a file in your drive with the name
return "https://drive.google.com/uc?id=" + str(image['id'])
return ""
@staticmethod
def get_folder_id(folder_path: str, element_index=0, last_parent=None) -> str:
"""
Gets the id of the given folder path, this function will create the folders, if they do not exist, so it will
always return a valid id, the folder_path elements can be separated like normals via a slash.
:param folder_path: Given folder path
:param element_index: Element index needed for recursive creation of the element
:param last_parent: Last parent only needed for recursive creation of the folder hierarchy
:return: The id to the last folder in the path
"""
folder_path_elements = folder_path.split("/")
if len(folder_path_elements) == element_index:
return last_parent
folder_list = GoogleDriveConnection.get().ListFile({'q': "mimeType='application/vnd.google-apps.folder' and trashed=false"}).GetList()
current_folder_name = folder_path_elements[element_index]
for item in folder_list:
if item['title'] == current_folder_name and item["parents"][0] == last_parent:
return GoogleDriveConnection.get_folder_id(folder_path, element_index + 1, item['id'])
# not in the list -> folder has to be created
file_metadata = {'title': current_folder_name, 'mimeType': 'application/vnd.google-apps.folder'}
if last_parent is not None:
file_metadata['parents'] = [{"id": last_parent}]
new_folder = GoogleDriveConnection.get().CreateFile(file_metadata)
new_folder.Upload()
return GoogleDriveConnection.get_folder_id(folder_path, element_index + 1, new_folder["id"])
这使您能够将图像加载到 Google 驱动器,如果您调用 get_folder_id
,它将为您提供该文件夹的 ID,如果该文件夹不存在,它将被创建。