Last active
November 7, 2022 20:57
-
-
Save efann/9c257b0b0b8a9a3a3a9f27a326d50598 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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