从dropbox API构建目录树

时间:2015-07-17 22:06:10

标签: python dropbox

我想做的是使用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']
    })

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

1 个答案:

答案 0 :(得分:2)

我稍微调整了你的结构......这里是下面代码产生的JSON表示。请注意,我已将内容字段设为由path而不是数组索引的字典。这样做更容易一点,并且可以更有效地查找,但如果您愿意,可以很容易地将其转换为上面的内容:

{
    "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)