从保管箱构建目录树 API
Build directory tree from dropbox API
我想做的是从保管箱 API 为给定路径构建一棵树,使用 python 为每个路径共享 links绑定。
我建议的结构如下所示:
[
{
'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()
,它将在一个请求中获取每个文件,然后将其构建到树中,但我在弄清楚具体方法时遇到了问题,尤其是如何将路径解析成树。
编辑:而且我已经意识到每个共享都有一个调用 link 所以我将省略这些并在需要时才获取它们。
这是我必须获得目前所需数据的一些代码:
paths = []
for path, metadata in client.delta(path_prefix='/whatever')['entries']:
paths.append({
'path': path,
'is_dir': metadata['is_dir']
})
所以我想我在弄清楚如何嵌套这些路径时遇到了麻烦。很确定我在这里需要一个递归函数,但不太明白。
我稍微调整了您的结构...这里是 JSON 下面代码生成的内容的表示。请注意,我已将内容字段设为按路径而不是数组索引的字典。这只是稍微简单一点,可以提高查找效率,但如果需要,应该很容易转换为上面的内容:
{
"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)
我想做的是从保管箱 API 为给定路径构建一棵树,使用 python 为每个路径共享 links绑定。
我建议的结构如下所示:
[
{
'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()
,它将在一个请求中获取每个文件,然后将其构建到树中,但我在弄清楚具体方法时遇到了问题,尤其是如何将路径解析成树。
编辑:而且我已经意识到每个共享都有一个调用 link 所以我将省略这些并在需要时才获取它们。
这是我必须获得目前所需数据的一些代码:
paths = []
for path, metadata in client.delta(path_prefix='/whatever')['entries']:
paths.append({
'path': path,
'is_dir': metadata['is_dir']
})
所以我想我在弄清楚如何嵌套这些路径时遇到了麻烦。很确定我在这里需要一个递归函数,但不太明白。
我稍微调整了您的结构...这里是 JSON 下面代码生成的内容的表示。请注意,我已将内容字段设为按路径而不是数组索引的字典。这只是稍微简单一点,可以提高查找效率,但如果需要,应该很容易转换为上面的内容:
{
"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)