Rohit
Rohit

Reputation: 189

Calculate Each dropbox folder size recursively using python api

EDIT: I want to calculate each folder size not just entire dropbox size... My code is working fine for whole dropbox size

I am having difficulty in calculating each folder size of dropbox using python api as dropbox returns folder size as zero

here's my code so far but it's giving me wrong answer

  def main(dp_path):
   a=  client.metadata(dp_path)
   size_local = 0
   for x in a['contents']:
     if x['is_dir']==False:
       global size
       size += int(x['bytes'])
       size_local += int(x['bytes'])

       #print "Total size so far :"+str(size/(1024.00*1024.00))+" Mb..." 


     if x['is_dir']==True:
       a = main(str(x['path']))
       print str(x['path'])+" size=="+str(a/(1024.00*1024.00))+" Mb..."

     return size_local+size


 if __name__ == '__main__':
   global size
   size=0
   main('/')
   print str(size/(1024.00*1024.00))+" Mb" 

Upvotes: 3

Views: 5331

Answers (1)

user94559
user94559

Reputation: 60143

EDIT 2: It seems I misunderstood the question. Here's code that prints out the sizes of each folder (in order of decreasing size):

from dropbox.client import DropboxClient
from collections import defaultdict

client = DropboxClient('<YOUR ACCESS TOKEN>')

sizes = {}
cursor = None
while cursor is None or result['has_more']:
    result = client.delta(cursor)
    for path, metadata in result['entries']:
        sizes[path] = metadata['bytes'] if metadata else 0
    cursor = result['cursor']

foldersizes = defaultdict(lambda: 0)
for path, size in sizes.items():
    segments = path.split('/')
    for i in range(1, len(segments)):
        folder = '/'.join(segments[:i])
        if folder == '': folder = '/'
        foldersizes[folder] += size

for folder in reversed(sorted(foldersizes.keys(), key=lambda x: foldersizes[x])):
    print '%s: %d' % (folder, foldersizes[folder])

EDIT: I had a major bug in the second code snippet (the delta one), and I've now tested all three and found them all to report the same number.

This works:

from dropbox.client import DropboxClient

client = DropboxClient('<YOUR ACCESS TOKEN>')

def size(path):
    return sum(
        f['bytes'] if not f['is_dir'] else size(f['path'])
        for f in client.metadata(path)['contents']
    )

print size('/')

But it's much more efficient to use /delta:

sizes = {}
cursor = None
while cursor is None or result['has_more']:
    result = client.delta(cursor)
    for path, metadata in result['entries']:
        sizes[path] = metadata['bytes'] if metadata else 0
    cursor = result['cursor']

print sum(sizes.values())

And if you truly just need to know the overall usage for the account, you can just do this:

quota_info = client.account_info()['quota_info']
print quota_info['normal'] + quota_info['shared']

Upvotes: 4

Related Questions