Python Google Drive API-列出整个驱动器文件树

问题描述 投票:7回答:4

[我正在构建一个使用Google驱动器API的python应用程序,因此开发起来不错,但是我在检索整个Google驱动器文件树时遇到问题,出于两个目的,我需要使用它:

  1. 检查路径是否存在,所以如果我想在root / folder1 / folder2下上传test.txt,我想检查文件是否已经存在,并在情况下进行更新
  2. [构建可视文件浏览器,现在我知道google提供了自己的文件名(我现在不记得这个名字了,但是我知道它已经存在了,但是我想将文件浏览器限制为特定的文件夹。

目前,我有一个获取Gdrive根目录的函数,我可以通过递归调用一个列出单个文件夹内容的函数来构建这三个目录,但是它非常慢,并且可能向Google和Google发出数千个请求这是不可接受的。

这里是获取根的函数:

def drive_get_root():
"""Retrieve a root list of File resources.
Returns:
List of dictionaries.
"""

#build the service, the driveHelper module will take care of authentication and credential storage
drive_service = build('drive', 'v2', driveHelper.buildHttp())
# the result will be a list
result = []
page_token = None
while True:
    try:
        param = {}
        if page_token:
            param['pageToken'] = page_token
        files = drive_service.files().list(**param).execute()
        #add the files in the list
        result.extend(files['items'])
        page_token = files.get('nextPageToken')
        if not page_token:
            break
    except errors.HttpError, _error:
        print 'An error occurred: %s' % _error
    break
return result

这里是从文件夹中获取文件的人

def drive_files_in_folder(folder_id):
"""Print files belonging to a folder.

Args:
folder_id: ID of the folder to get files from.
"""
#build the service, the driveHelper module will take care of authentication and credential storage
drive_service = build('drive', 'v2', driveHelper.buildHttp())
# the result will be a list
result = []
#code from google, is working so I didn't touch it
page_token = None
while True:
    try:
        param = {}

        if page_token:
            param['pageToken'] = page_token

        children = drive_service.children().list(folderId=folder_id, **param).execute()

        for child in children.get('items', []):
            result.append(drive_get_file(child['id']))

        page_token = children.get('nextPageToken')
        if not page_token:
            break
    except errors.HttpError, _error:
        print 'An error occurred: %s' % _error
        break
return result

例如,现在要检查文件是否存在,我正在使用此文件:

def drive_path_exist(file_path, list = False):
"""
This is a recursive function to che check if the given path exist
"""

#if the list param is empty set the list as the root of Gdrive
if list == False:
    list = drive_get_root()

#split the string to get the first item and check if is in the root
file_path = string.split(file_path, "/")

#if there is only one element in the filepath we are at the actual filename
#so if is in this folder we can return it
if len(file_path) == 1:
    exist = False
    for elem in list:
        if elem["title"] == file_path[0]:
            #set exist = to the elem because the elem is a dictionary with all the file info
            exist = elem

    return exist
#if we are not at the last element we have to keep searching
else:
    exist = False
    for elem in list:
        #check if the current item is in the folder
        if elem["title"] == file_path[0]:
            exist = True
            folder_id = elem["id"]
            #delete the first element and keep searching
            file_path.pop(0)

    if exist:
        #recursive call, we have to rejoin the filpath as string an passing as list the list
        #from the drive_file_exist function
        return drive_path_exist("/".join(file_path), drive_files_in_folder(folder_id))

任何想法如何解决我的问题?我在这里看到了一些有关溢出的讨论,人们在一些回答中写道这是可能的,但是当然并没有说如何!

谢谢

python google-api google-drive-api
4个回答
11
投票

停止将Drive视为树形结构。不是。 “文件夹”只是标签,例如。一个文件可以有多个父母。

为了在您的应用中构建树的表示,您需要执行此操作...

  1. 运行驱动器列表查询以检索所有文件夹
  2. 迭代结果数组并检查parents属性以构建内存层次结构
  3. 运行第二个驱动器列表查询以获取所有非文件夹(即文件)
  4. 对于返回的每个文件,请将其放在内存树中

如果只想检查文件夹-B中是否存在文件-A,则方法取决于名称“文件夹-B”是否保证是唯一的。

如果是唯一的,只需对标题='file-A'进行FilesList查询,然后为其每个父项执行Files Get,并查看它们中的任何一个是否被称为'folder-B'。

如果“文件夹-B”可以同时存在于“文件夹-C”和“文件夹-D”下,则它会更加复杂,您将需要根据上述步骤1和步骤2构建内存中的层次结构。

您不说这些文件和文件夹是由您的应用还是由Google Drive Webapp的用户创建的。如果您的应用是这些文件/文件夹的创建者,那么可以使用一种技巧来将搜索限制在单个根目录下。说你有

MyDrive/app_root/folder-C/folder-B/file-A

您可以将app_root的所有文件夹-C,文件夹-B和文件-A设为子代>

这样,您可以约束所有查询以包括

and 'app_root_id' in parents
    

3
投票

除了很小的树,永远不会那样工作。您必须重新考虑云应用程序的整个算法(您将其编写为拥有计算机的台式机应用程序一样),因为它很容易超时。您需要预先镜像树(任务队列和数据存储),不仅是为了避免超时,而且还要避免驱动速率限制,并以某种方式使其保持同步(注册推送等)。一点都不容易。我之前做过驱动器树查看器。


1
投票

检查文件在特定路径中是​​否存在的简单方法是:drive_service.files()。list(q =“'THE_ID_OF_SPECIFIC_PATH'在父母和标题='一个文件'”).execute()


0
投票

使用Google Drive Rest递归搜索文件https://stackoverflow.com/a/62372105/10435989

© www.soinside.com 2019 - 2024. All rights reserved.