Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从dropbox API构建目录树_Python_Dropbox - Fatal编程技术网

Python 从dropbox API构建目录树

Python 从dropbox API构建目录树,python,dropbox,Python,Dropbox,我想做的是使用python绑定从dropbox API为给定路径构建一个树,每个路径都有共享链接 我提议的结构如下所示: [ { 'path': '/a', 'is_dir': True, 'contents': [ { 'path': '/a/b', 'is_dir': True, 'contents': [etc]

我想做的是使用python绑定从dropbox API为给定路径构建一个树,每个路径都有共享链接

我提议的结构如下所示:

[
    {
        'path': '/a',
        'is_dir': True,
        'contents': [
            {
                'path': '/a/b',
                'is_dir': True,
                'contents': [etc]
            },
            {
                'path': '/a/readme.txt',
                'is_dir': False,
                'share_link': 'http://etc'
            }
        ]
    },
    etc.
]
我有一些东西主要使用
metadata()
工作,但速度非常慢,因为它需要对遍历的每个目录进行API调用

我想使用的是
delta()
,它将在一个请求中获取每个文件,然后将其构建到一个树中,但我很难准确地理解如何,特别是如何将路径解析到一个树中

编辑:我意识到每个共享链接都有一个调用,所以我将省略这些,并在请求时获取它们

以下是一些代码,我必须获得到目前为止所需的数据:

paths = []

for path, metadata in client.delta(path_prefix='/whatever')['entries']:
    paths.append({
        'path': path,
        'is_dir': metadata['is_dir']
    })

所以我想我很难弄清楚如何嵌套这些路径。我很确定这里需要一个递归函数,但我还不能完全理解它。

我稍微调整了一下您的结构。。。下面是下面代码生成的JSON表示。请注意,我将contents字段设置为按路径索引的字典,而不是数组。这只是简单了一点,有助于更高效的查找,但如果您愿意,应该很容易将其转换为上述内容:

{
    "is_dir": true,
    "contents": {
        "/foo.txt": {
            "is_dir": false,
            "contents": {}
        },
        "/a": {
            "is_dir": true,
            "contents": {
                "/a/bar.txt": {
                    "is_dir": false,
                    "contents": {}
                },
                "/a/b": {
                    "is_dir": true,
                    "contents": {
                        "/a/b/hello.txt": {
                            "is_dir": false,
                            "contents": {}
                        }
                    }
                }
            }
        }
    }
}
下面是生成该输出的代码:

ACCESS_TOKEN = '<REDACTED>'

from collections import defaultdict
import json

from dropbox.client import DropboxClient

def make_tree():
    return {
        'is_dir': True,
        'contents': defaultdict(make_tree)
    }
tree = defaultdict(make_tree)

client = DropboxClient(ACCESS_TOKEN)

has_more = True
cursor = None

while has_more:
    delta = client.delta(cursor)

    cursor = delta['cursor']
    has_more = delta['has_more']

    for path, metadata in delta['entries']:
        if metadata is not None:

            # find the right place in the tree
            segments = path.split('/')
            location = tree['/']
            for i in xrange(1, len(segments)-1):
                current_path = '/'.join(segments[:i+1])
                location = location['contents'][current_path]

            # insert the new entry
            location['contents'][path] = {
                'is_dir': metadata['is_dir'],
                'contents': {}
            }

print json.dumps(tree['/'], indent=4)
ACCESS\u TOKEN=''
从集合导入defaultdict
导入json
从dropbox.client导入dropbox客户端
def make_tree():
返回{
“is_dir”:正确,
“内容”:defaultdict(生成树)
}
tree=defaultdict(生成树)
client=DropboxClient(访问令牌)
有更多=真的吗
游标=无
而你有更多:
delta=client.delta(游标)
游标=增量['cursor']
has_more=delta['has_more']
对于路径,增量['entries']中的元数据:
如果元数据不是无:
#在树上找到正确的位置
segments=路径。拆分(“/”)
位置=树['/']
对于X范围内的i(1,长度(段)-1):
当前路径=“/”。连接(段[:i+1])
位置=位置['contents'][当前路径]
#插入新条目
位置['contents'][path]={
'is_dir':元数据['is_dir'],
'目录':{}
}
打印json.dumps(树['/',缩进=4)

HTTP文档/delta有一些关于返回数据的更多信息:这篇博文虽然是用Python写的,但可能有一些用处:
/delta
肯定是枚举文件的方法,但您仍然需要为每个文件创建一个共享链接,对吗?这将是缓慢的部分。我想你们错过了python标记,所以我将进行编辑以使其更清楚。谢谢!这几乎可以完美地工作,但有一件事-如果我使用前缀调用
delta()
,比如
delta(游标,/a/prefix')
/
仍然位于树的根。我可以将其更改为指定的前缀,但在
/a/prefix
下是另一个冗余的
/a/prefix
。有什么想法吗?没必要在那里耍花招。。。这听起来像是一个
if
语句可以解决这个问题。:-)现在我想起来了,这还不是问题所在。问题是,如果我指定一个前缀,
/a/prefix
,它当前会显示
/a
/a/prefix
,尽管我没有从它们那里获取文件。实际上,如果我指定一个前缀,我希望该前缀是根,并且不在其上显示任何内容。我想我通过在for循环中将路径前缀替换为空字符串来解决这个问题,但它看起来有点混乱。