Skip to content

Instantly share code, notes, and snippets.

@efann
Last active November 7, 2022 20:57
Show Gist options
  • Save efann/9c257b0b0b8a9a3a3a9f27a326d50598 to your computer and use it in GitHub Desktop.
Save efann/9c257b0b0b8a9a3a3a9f27a326d50598 to your computer and use it in GitHub Desktop.
# License: Eclipse Public License - v 2.0 (https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html)
# Updated on November 7, 2022
#
# Python routine for copying a complete directory structure up to Dropbox.
# Uses Python SDK for API v2
# https://www.dropbox.com/developers/documentation/python
import dropbox
import os
import time
from datetime import timedelta
from dropbox.files import WriteMode
from dropbox.exceptions import ApiError
# ---------------------------------------------------------------------------------------------------------------------
# Add OAuth2 access token here.
# You can generate one for yourself in the App Console.
# See <https://blogs.dropbox.com/developers/2014/05/generate-an-access-token-for-your-own-account/>
TOKEN = '<token>'
# Do not end with a slash: otherwise the Dropbox path will not have
# a root slash with lcFullPath.replace(TOP_FOLDER, '')
TOP_FOLDER = '/backup/current'
SEPARATOR = '============================================================================================='
# You cannot upload more than 150 MB of file contents per request. I decided to cap the limit
# at 100 Megs . . . just because.
CHUNK_SIZE = 96 * 1024 * 1024
# ---------------------------------------------------------------------------------------------------------------------
def upload_to_dropbox():
loDropbox = dropbox.Dropbox(TOKEN)
for lcSubDir, laDirNames, laFiles in os.walk(TOP_FOLDER):
for lcFile in laFiles:
lcFullPath = os.path.join(lcSubDir, lcFile)
lcDropboxPath = lcFullPath.replace(TOP_FOLDER, '')
print(SEPARATOR)
print('Uploading ' + lcFullPath + ' to ' + lcDropboxPath)
lnFileSize = os.path.getsize(lcFullPath)
try:
with open(lcFullPath, 'rb') as loFileHandle:
if (lnFileSize <= CHUNK_SIZE):
loData = loFileHandle.read()
loDropbox.files_upload(loData, lcDropboxPath, dropbox.files.WriteMode.overwrite)
else:
print('Size of ', "{:,}".format(lnFileSize), ' greater than ', "{:,}".format(CHUNK_SIZE), ' so implementing upload session.')
upload_session_start_result = loDropbox.files_upload_session_start(loFileHandle.read(CHUNK_SIZE))
lnSessionID = upload_session_start_result.session_id
loCursor = dropbox.files.UploadSessionCursor(lnSessionID, offset=loFileHandle.tell())
loCommit = dropbox.files.CommitInfo(path=lcDropboxPath, mode=dropbox.files.WriteMode.overwrite)
while (loFileHandle.tell() < lnFileSize):
if ((lnFileSize - loFileHandle.tell()) <= CHUNK_SIZE):
ignore = loDropbox.files_upload_session_finish(loFileHandle.read(CHUNK_SIZE), loCursor, loCommit)
else:
loDropbox.files_upload_session_append_v2(loFileHandle.read(CHUNK_SIZE), loCursor)
loCursor.offset = loFileHandle.tell()
except dropbox.exceptions.ApiError as loErr:
print('Error in uploading ' + lcFullPath)
print(loErr)
# ---------------------------------------------------------------------------------------------------------------------
# Good explanation on __main__ from
# http://stackoverflow.com/questions/419163/what-does-if-name-main-do
if __name__ == "__main__":
# Timer from http://stackoverflow.com/questions/1557571/how-to-get-time-of-a-python-program-execution/1557906#1557906
loStartTime = time.time()
upload_to_dropbox()
loElapsedTimeSeconds = time.time() - loStartTime
print(SEPARATOR)
print("Uploading took: %s (hours:minutes:seconds)" % timedelta(seconds=round(loElapsedTimeSeconds)))
# ---------------------------------------------------------------------------------------------------------------------
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment