Reputation: 6616
What I'd like to do is to build a tree from the dropbox API, for a given path, with share links for each path, using the python bindings.
My proposed structure looks something like this:
[
{
'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.
]
I've got something that mostly works using metadata()
but it's hideously slow as it needs to make an API call per directory traversed.
What I'd like to use instead is delta()
, which will get me every file in one request, then build it into a tree, but I'm having problems figuring out exactly how, in particular how to parse the paths into a tree.
Edit: And I've realised there's a call for each share link so I'm going to omit those and just get them when requested.
Here's some code I have to get the data I need so far:
paths = []
for path, metadata in client.delta(path_prefix='/whatever')['entries']:
paths.append({
'path': path,
'is_dir': metadata['is_dir']
})
So I guess I'm having trouble figuring out how to get those paths nested. Pretty sure I need a recursive function here but can't quite figure it out.
Upvotes: 2
Views: 1093
Reputation: 60143
I tweaked your structure just a bit... here's the JSON representation of what the below code produces. Note that I've made the contents field a dictionary indexed by path instead of an array. This is just a little easier and makes for more efficient lookup, but it should be pretty easy to convert to exactly what you have above if you want:
{
"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": {}
}
}
}
}
}
}
}
Here's the code that produces that output:
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)
Upvotes: 2