Skip to content

Instantly share code, notes, and snippets.

@omz
Last active November 16, 2025 11:09
Show Gist options
  • Select an option

  • Save omz/fb180c58c94526e2c40b to your computer and use it in GitHub Desktop.

Select an option

Save omz/fb180c58c94526e2c40b to your computer and use it in GitHub Desktop.

Revisions

  1. omz revised this gist Jan 12, 2016. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions Dropbox File Picker.py
    Original file line number Diff line number Diff line change
    @@ -146,6 +146,7 @@ def c(o1, o2):
    self.name = self.path

    root_view = DropboxView()
    root_view.frame = (0, 0, 500, 500)
    root_view.present('sheet')
    root_view.load_folder()

  2. omz created this gist Jun 17, 2014.
    151 changes: 151 additions & 0 deletions Dropbox File Picker.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,151 @@
    # IMPORTANT SETUP INSTRUCTIONS:
    #
    # 1. Go to http://www.dropbox.com/developers/apps (log in if necessary)
    # 2. Select "Create App"
    # 3. Select the following settings:
    # * "Dropbox API app"
    # * "Files and datastores"
    # * "(No) My app needs access to files already on Dropbox"
    # * "All file types"
    # * (Choose any app name)
    # 4. On the newly-created app's summary page, click the "Generate"
    # button under "Generated access token"
    # 5. Copy the generated token (a long string of gibberish) and
    # paste it below (replace YOUR_TOKEN_HERE).
    # 6. (optional) Open the "wrench" (actions) menu in Pythonista and add
    # this script, so you can run it from everywhere.

    # Notes:
    # All selected files are downloaded into the root folder of the Pythonista
    # script library. If a file with the same name already exists, a numeric
    # suffix is appended automatically.

    TOKEN = 'YOUR_TOKEN_HERE'

    import requests
    import urllib
    import os
    import ui

    def list_folder(folder_path='/'):
    headers = {'Authorization': 'Bearer %s' % (TOKEN,)}
    r = requests.get('https://api.dropbox.com/1/metadata/dropbox/%s?list=true' % (urllib.quote(folder_path.encode('utf-8')),), headers=headers)
    result = r.json()
    return result.get('contents', None)

    def download_file(path, dest_filename, progress=None):
    headers = {'Authorization': 'Bearer %s' % (TOKEN,)}
    url_path = urllib.quote(path.encode('utf-8'))
    url = 'https://api-content.dropbox.com/1/files/dropbox/%s' % (url_path,)
    r = requests.get(url, stream=True, headers=headers)
    dest_path = os.path.join(os.path.expanduser('~/Documents'), dest_filename)
    i = 1
    while os.path.exists(dest_path):
    base, ext = os.path.splitext(dest_filename)
    dest_path = os.path.join(os.path.expanduser('~/Documents'), base + '-' + str(i) + ext)
    i += 1
    size = r.headers.get('Content-Length', 0)
    bytes_written = 0
    canceled = False
    with open(dest_path, 'w') as f:
    for chunk in r.iter_content(1024*10):
    f.write(chunk)
    bytes_written += len(chunk)
    if size > 0 and callable(progress):
    p = float(bytes_written) / float(size)
    should_cancel = progress(p)
    if should_cancel:
    canceled = True
    break
    if canceled:
    os.remove(dest_path)

    class DropboxView (ui.View):
    def __init__(self, path='/'):
    tv = ui.TableView()
    tv.frame = self.bounds
    tv.flex = 'WH'
    ds = ui.ListDataSource([])
    ds.action = self.item_selected
    tv.data_source = ds
    tv.delegate = ds
    self.tableview = tv
    self.add_subview(self.tableview)
    self.name = 'Dropbox'
    label = ui.Label(frame=self.bounds)
    label.flex = 'WH'
    label.background_color = (1, 1, 1, 0.95)
    label.text = 'Loading...'
    label.touch_enabled = True
    label.alignment = ui.ALIGN_CENTER
    self.path = path
    self.add_subview(label)
    self.status_label = label
    self.canceled = False

    def will_close(self):
    self.canceled = True

    def item_selected(self, sender):
    item = sender.items[sender.selected_row]
    if item.get('is_dir', False):
    self.status_label.text = 'Loading Folder...'
    self.status_label.hidden = False
    self.path = item['path']
    self.load_folder()
    elif item.get('up', False):
    self.status_label.text = 'Loading Folder...'
    self.status_label.hidden = False
    self.path = os.path.split(self.path)[0]
    self.load_folder()
    else:
    path = item.get('path')
    self.download_file(path)

    @ui.in_background
    def download_file(self, path):
    self.status_label.text = 'Downloading %s...' % (path,)
    self.status_label.hidden = False
    download_file(path, os.path.split(path)[1], self.download_progress)
    self.status_label.hidden = True

    def download_progress(self, p):
    self.status_label.text = '%i %% Downloaded...' % (p*100,)
    return self.canceled

    @ui.in_background
    def load_folder(self):
    infos = list_folder(self.path)
    items = []
    if self.path != '/':
    items.append({'title': '..', 'image': 'ionicons-arrow-up-c-32', 'up': True})
    if not infos:
    import console
    console.alert('Error', 'Could not load folder. Please check if you entered the access token correctly.', 'OK', hide_cancel_button=True)
    self.status_label.hidden = True
    return
    for info in infos:
    path = info.get('path')
    name = os.path.split(path)[1]
    if name.startswith('.'):
    continue
    is_dir = info.get('is_dir', False)
    item = {'title': name, 'image': 'ionicons-folder-32' if is_dir else 'ionicons-ios7-download-outline-32', 'accessory_type': 'disclosure_indicator' if is_dir else 'none', 'is_dir': is_dir, 'path': info['path']}
    items.append(item)
    def c(o1, o2):
    u_cmp = -1 * cmp(o1.get('up', False), o2.get('up', False))
    if u_cmp != 0:
    return u_cmp
    d_cmp = -1 * cmp(o1.get('is_dir', False), o2.get('is_dir', False))
    if d_cmp == 0:
    return cmp(o1.get('path', '').lower(), o2.get('path', '').lower())
    return d_cmp
    items.sort(cmp=c)
    self.tableview.data_source.items = items
    self.status_label.hidden = True
    self.name = self.path

    root_view = DropboxView()
    root_view.present('sheet')
    root_view.load_folder()