File: //volume1/@appstore/HyperBackup/addon/dropbox/python/dropbox_agent.py
#!/usr/bin/env python
#-*-coding: utf-8 -*-
import os, sys, json
from struct import pack, unpack
from syslog import syslog, LOG_ERR
PY3 = sys.version_info[0] == 3
# add include path
script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
sys.path.insert(0, script_dir + '/module')
import dropbox
from dropbox.files import WriteMode
from dropbox.files import UploadSessionCursor
import requests
debug = False
def log_debug(*args):
if debug:
print >> sys.stderr, ' '.join(args)
def _is_scoket_exception(e):
import socket
if type(e) == socket.gaierror or type(e) == socket.error or type(e) == socket.herror or type(e) == socket.timeout:
return True
return False
def _convert_socket_error_code(message):
error_code = -1
if -1 != message.find("[Errno -2] Name or service not known"):
error_code = -2
elif -1 != message.find("[Errno -3] Temporary failure in name resolution"):
error_code = -2
elif -1 != message.find("[Errno -5] No address associated with hostname"):
error_code = -2
elif -1 != message.find("[Errno 110] Connection timed out"):
error_code = 408
elif -1 != message.find("[Errno 101] Network is unreachable"):
error_code = -4
elif -1 != message.find("[Errno 111] Connection refused"):
error_code = -4
elif -1 != message.find("[Errno 113] No route to host"):
error_code = -4
elif -1 != message.find("[Errno 104] Connection reset by peer"):
error_code = -4
elif -1 != message.find("[Errno 32] Broken pipe"):
error_code = 408
return error_code
def _is_ssl_timeout(message):
#ssl.SSLErr_timeouteption log
if -1 != message.find("timed out"):
# The read operation timed out
# The write operation timed out
# The handshake operation timed out
return True
return False
def _convert_socket_exception(e):
import socket
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
if type(e) == socket.gaierror:
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
if e.errno == -2:
# socket.gaierror: [Errno -2] Name or service not known
# 1. dns not set
# 2. set to a wrong dns
error_code = -2
elif e.errno == -3:
# socket.gaierror: [Errno -3] Temporary failure in name resolution
# man gai_strerror, and find EAI_AGAIN:
# The name server returned a temporary failure indication. Try again later.
error_code = -2
elif e.errno == -5:
# socket.gaierror: [Errno -5] No address associated with hostname
# man gai_strerror, and find EAI_NODATA:
# The specified network host exists, but does not have any network addresses defined.
error_code = -2
elif e.errno < 100 and e.errno > 0:
error_code = e.errno
elif type(e) == socket.error or type(e) == socket.herror:
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
if e.errno == socket.errno.ETIMEDOUT:
# socket.error: [Errno 110] Connection timed out
error_code = 408
elif e.errno == socket.errno.ENETUNREACH:
# socket.error: [Errno 101] Network is unreachable
error_code = -4
elif e.errno == socket.errno.ECONNREFUSED:
# socket.error: [Errno 111] Connection refused
error_code = -4
elif e.errno == socket.errno.EHOSTUNREACH:
# socket.error: [Errno 113] No route to host
error_code = -4
elif e.errno == socket.errno.ECONNRESET:
# socket.error: [Errno 104] Connection reset by peer
error_code = -4
elif e.errno == socket.errno.EPIPE:
# socket.error: [Errno 32] Broken pipe
error_code = 408
elif e.errno < 100 and e.errno > 0:
error_code = e.errno
#syslog(LOG_ERR, "get network error %d:%s" % (e.errno, error_msg))
elif type(e) == socket.timeout:
error_msg = 'timed out'
error_code = 408
elif type(e) == requests.exceptions.ChunkedEncodingError:
error_code = -4
else:
syslog(LOG_ERR, "BUG: exception [%s], type [%s]" % (str(e), type(e)))
#syslog(LOG_ERR, "error %s:%d:%s" % (error_cls, error_code, str(error_msg)))
if -1 == error_code:
if hasattr(e, "args"):
syslog(LOG_ERR, "error args: [%s]" % (str(e.args)))
if hasattr(e, "errno"):
syslog(LOG_ERR, "error errno: [%s]" % (str(e.errno)))
if hasattr(e, "strerror"):
syslog(LOG_ERR, "error strerror: [%s]" % (str(e.strerror)))
except Exception as ee:
syslog(LOG_ERR, "parse socket exception failed: [%s]" % (str(ee)))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_dropbox_write_error(e):
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
error_msg = str(e)
if e.is_conflict():
#Couldn’t write to the target path because there was something in the way
if e.get_conflict().is_folder():
error_code = 10001
elif e.get_conflict().is_file_ancestor():
error_code = 10002
elif e.get_conflict().is_file():
error_code = 10003
elif e.get_conflict().is_other():
error_code = 10004
elif e.is_malformed_path():
error_code = 400
elif e.is_disallowed_name():
#Dropbox will not save the file or folder because of its name.
error_code = 400
elif e.is_insufficient_space():
#The user doesn’t have enough available space (bytes) to write more data.
error_code = 507
elif e.is_no_write_permission():
#The user doesn’t have permissions to write to the target location.
error_code = 403
elif e.is_too_many_write_operations():
#There are too many write operations
#happening in the user's Dropbox. You should retry uploading this file.
error_code = 429
elif e.is_team_folder():
#This endpoint cannot move or delete team folders.
error_code = 10031
elif e.is_other():
error_code = -1
except Exception as e:
syslog(LOG_ERR, "parse dropbox write exception failed. %s" % str(e))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_dropbox_lookup_error(e):
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
error_msg = str(e)
if e.is_malformed_path():
error_code = 400
elif e.is_not_file():
#We were expecting a file, but the given path refers to something that isn’t a file.
error_code = 10011
elif e.is_not_folder():
#We were expecting a folder, but the given path refers to something that isn’t a folder.
error_code = 10012
elif e.is_not_found():
#There is nothing at the given path.
error_code = 404
elif e.is_restricted_content():
#The file cannot be transferred because the content is restricted.
#For example, sometimes there are legal restrictions due to copyright claims.
error_code = 10013
elif e.is_unsupported_content_type():
#This operation is not supported for this content type.
error_code = 10014
elif e.is_other():
error_code = -1
except Exception as e:
syslog(LOG_ERR, "parse dropbox lookup exception failed. %s" % str(e))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_dropbox_upload_session_lookup_error(e):
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
error_msg = str(e)
if e.is_incorrect_offset():
#This error may occur when a previous request was received and processed successfully but the client did not receive the response
#e.g. due to a network error.
error_code = 10021
elif e.is_closed():
#You are attempting to append data to an upload session that has alread been closed (i.e. committed).
error_code = -4
elif e.is_not_closed():
#The session must be closed before calling upload_session/finish_batch.
error_code = -1
elif e.is_not_found():
#The upload session id was not found
error_code = -1
elif e.is_too_large():
#You can not append to the upload session because the size
#of a file should not reach the max file size limit (i.e. 350GB).
error_code = 413
elif e.is_other():
error_code = -1
except Exception as e:
syslog(LOG_ERR, "parse dropbox upload session exception failed. %s" % str(e))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_dropbox_exception(e):
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
error_msg = str(e)
if type(e) == dropbox.files.CreateFolderError:
if e.is_path():
return _convert_dropbox_write_error(e.get_path())
elif type(e) == dropbox.files.GetMetadataError:
if e.is_path():
return _convert_dropbox_lookup_error(e.get_path())
elif type(e) == dropbox.files.ListFolderError:
if e.is_path():
return _convert_dropbox_lookup_error(e.get_path())
elif e.is_other():
error_code = -1
elif type(e) == dropbox.files.ListFolderContinueError:
if e.is_path():
return _convert_dropbox_lookup_error(e.get_path())
elif e.is_reset():
#Indicates that the cursor has been invalidated. Call
#dropbox.dropbox.Dropbox.files_list_folder() to obtain a new cursor.
error_code = -1
elif e.is_other():
error_code = -1
elif type(e) == dropbox.files.DeleteError:
if e.is_path_lookup():
return _convert_dropbox_lookup_error(e.get_path_lookup())
elif e.is_path_write():
return _convert_dropbox_write_error(e.get_path_write())
elif e.is_too_many_files():
error_code = 406
elif e.is_too_many_write_operations():
#There are too many write operations
#happening in the user's Dropbox. You should retry uploading this file.
error_code = 429
elif e.is_other():
error_code = -1
elif type(e) == dropbox.files.UploadError:
if e.is_path():
return _convert_dropbox_write_error(e.get_path().reason)
elif e.is_properties_error():
#The supplied property group is invalid. The file has uploaded without
# property groups.
error_code = -1
elif e.is_other():
error_code = -1
elif type(e) == dropbox.files.UploadSessionLookupError:
return _convert_dropbox_upload_session_lookup_error(e)
elif type(e) == dropbox.files.UploadSessionFinishError:
if e.is_lookup_failed():
#The session arguments are incorrect; the value explains the reason.
return _convert_dropbox_upload_session_lookup_error(e.get_lookup_failed())
elif e.is_path():
#Unable to save the uploaded contents to a file.
return _convert_dropbox_write_error(e.get_path())
elif e.is_too_many_shared_folder_targets():
#The batch request commits files into too many different shared folders.
#Please limit your batch request to files contained in a single shared folder.
error_code = -1
elif e.is_too_many_write_operations():
#There are too many write operations
#happening in the user's Dropbox. You should retry uploading this file.
error_code = 429
elif e.is_properties_error():
#The supplied property group is invalid. The file has uploaded without
# property groups.
error_code = -1
elif e.is_other():
error_code = -1
elif type(e) == dropbox.files.DownloadError:
if e.is_path():
return _convert_dropbox_lookup_error(e.get_path())
elif e.is_other():
error_code = -1
except Exception as e:
syslog(LOG_ERR, "parse dropbox exception failed. %s" % str(e))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_exception(e):
#syslog(LOG_ERR, "convert_exception: %s" % str(e))
import socket
import httplib
import ssl
error_code = -1
error_msg = 'Unknown'
error_cls = 'Unknown'
try:
error_cls = type(e).__name__
if hasattr(e, '__module__') and e.__module__:
error_cls = e.__module__ + '.' + error_cls
try:
if type(e.message) is unicode:
error_msg = repr(e.message).split('\\n')[0]
else:
error_msg = str(e.message).split('\n')[0]
log_debug("\033[31mexception: \033[0m", error_msg)
except:
log_debug("\033[31mexception: \033[0m", "could not parse error msg")
if type(e) == dropbox.exceptions.ApiError:
#syslog(LOG_ERR, "dropbox Api error %s:%s:%s" % (str(e.request_id), str(e.error), str(e.user_message_text)))
return _convert_dropbox_exception(e.error)
elif type(e) == dropbox.exceptions.AuthError:
error_code = 401
error_msg = str(e.error)
elif type(e) == dropbox.exceptions.BadInputError:
error_code = 400
elif type(e) == dropbox.exceptions.DropboxException:
#All errors related to making an API request extend this
error_code = -1
error_msg = str(e)
elif type(e) == dropbox.exceptions.HttpError:
#Errors produced at the HTTP layer
error_code = e.status_code
error_msg = str(e)
elif type(e) == dropbox.exceptions.InternalServerError:
#Errors due to a problem on Dropbox
error_code = e.status_code
error_msg = str(e)
elif type(e) == dropbox.exceptions.RateLimitError:
#Error caused by rate limiting
error_code = 429
error_msg = str(e)
elif type(e) == TypeError:
# this exception will raise when base64 decode for auth failed
if error_msg == "Incorrect padding":
error_code = 401
elif type(e) == UnicodeDecodeError:
error_code = -5
elif type(e) == requests.exceptions.ConnectionError:
error_code = -4
if type(e.args[0]) == requests.packages.urllib3.exceptions.ProtocolError:
if "BadStatusLine" in str(e.args[0]):
error_code = -4
elif _is_scoket_exception(e.args[0].args[1]):
return _convert_socket_exception(e.args[0].args[1])
else:
syslog(LOG_ERR, "ProtocolError: exception [%s], type [%s]" % (str(e.args[0].args[1]), type(e.args[0].args[1])))
elif type(e.args[0]) == requests.packages.urllib3.exceptions.MaxRetryError:
if hasattr(e.args[0], 'reason') and e.args[0].reason:
if type(e.args[0].reason) == requests.packages.urllib3.exceptions.NewConnectionError:
error_code = _convert_socket_error_code(str(e.args[0].reason))
else:
syslog(LOG_ERR, "MaxRetryError: exception [%s], type [%s]" % (str(e.args[0].reason), type(e.args[0].reason)))
elif _is_scoket_exception(e.args[0]):
return _convert_socket_exception(e.args[0])
elif type(e.args[0]) == ssl.SSLError or type(e.args[0]) == requests.packages.urllib3.exceptions.SSLError:
if hasattr(e.args[0], 'message') and e.args[0].message:
error_msg = e.args[0].message
if _is_ssl_timeout(str(error_msg)):
error_code = 408
else:
syslog(LOG_ERR, "SSLError: exception [%s], type [%s]" % (str(error_msg), type(error_msg)))
elif type(e) == requests.exceptions.SSLError:
error_code = -4
# EOF occurred in violation of protocol
# SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC
# SSL: SSLV3_ALERT_BAD_RECORD_MAC
# SSL: SSLV3_ALERT_ILLEGAL_PARAMETER
# SSL: TLSV1_ALERT_DECRYPT_ERROR
# SSL: TLSV1_ALERT_DECODE_ERROR
# SSL: CERTIFICATE_VERIFY_FAILED
if _is_ssl_timeout(str(e)):
error_code = 408
elif type(e) == requests.packages.urllib3.exceptions.NewConnectionError:
error_code = _convert_socket_error_code(str(e))
elif type(e) == requests.packages.urllib3.exceptions.ConnectTimeoutError:
error_code = 408
elif type(e) == requests.packages.urllib3.exceptions.ReadTimeoutError:
error_code = 408
elif type(e) == requests.exceptions.ConnectTimeout:
error_code = 408
elif type(e) == requests.exceptions.ReadTimeout:
error_code = 408
elif type(e) == httplib.ResponseNotReady:
error_code = -4
elif type(e) == httplib.BadStatusLine:
error_code = -4
elif type(e) == httplib.IncompleteRead:
error_code = -4
elif type(e) == ssl.SSLError:
error_code = -4
if hasattr(e, "strerror") and e.strerror:
# SSL: DECRYPTION_FAILED_OR_BAD_RECORD_MAC
# SSL: SSLV3_ALERT_BAD_RECORD_MAC
# SSL: CERTIFICATE_VERIFY_FAILED
error_msg = e.strerror
if _is_ssl_timeout(str(error_msg)):
error_code = 408
elif type(e) == ssl.SSLEOFError:
# ssl.SSLEOFError: [Errno 8] EOF occurred in violation of protocol
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
error_code = -4
elif type(e) == IOError:
if hasattr(e, 'strerror') and e.strerror:
error_msg = e.strerror
error_code = _convert_socket_error_code(str(e))
elif _is_scoket_exception(e):
return _convert_socket_exception(e)
else:
syslog(LOG_ERR, "exception [%s]" % str(e))
syslog(LOG_ERR, "type [%s]" % type(e))
#syslog(LOG_ERR, "error %s:%d:%s" % (error_cls, error_code, str(error_msg)))
if -1 == error_code:
if hasattr(e, "args"):
syslog(LOG_ERR, "error args: [%s]" % (str(e.args)))
if hasattr(e, "errno"):
syslog(LOG_ERR, "error errno: [%s]" % (str(e.errno)))
if hasattr(e, "strerror"):
syslog(LOG_ERR, "error strerror: [%s]" % (str(e.strerror)))
except Exception as ee:
syslog(LOG_ERR, "parse exception failed: [%s]" % (str(ee)))
pass
return {
'success': False,
'error_class': error_cls,
'error_message': error_msg,
'error_code': error_code
}
def _convert_time(val):
if val is None:
return 0
import calendar
return calendar.timegm(val)
def _convert_properties(properties):
out_json = {}
if type(properties) is dropbox.files.FolderMetadata:
out_json = {
'is_dir': True,
'path': properties.path_display,
}
elif type(properties) is dropbox.files.FileMetadata:
out_json = {
'LastModified': _convert_time(properties.server_modified.utctimetuple()),
'ContentLength': properties.size,
'is_dir': False,
'path': properties.path_display,
'id': properties.id,
'rev': properties.rev,
'is_downloadable': properties.is_downloadable,
'content_hash': properties.content_hash,
'client_modified': _convert_time(properties.client_modified.utctimetuple())
}
elif type(properties) is dropbox.files.DeletedMetadata:
out_json = {
'is_deleted': True,
'path': properties.path_display,
}
return out_json
class SimpleIO(object):
def read_int(self):
data = ''
n = 4
while n > 0:
read_data = sys.stdin.read(n)
if 0 == len(read_data):
raise StopIteration
data += read_data
n -= len(read_data)
if data:
return unpack('i', data)[0]
else:
# check eof?
raise StopIteration
def read_string(self):
n = self.read_int()
if 0 == n:
return ''
data = ''
while n > 0:
read_data = sys.stdin.read(n)
if 0 == len(read_data):
raise StopIteration
data += read_data
n -= len(read_data)
if data:
return data
else:
raise SystemError
def read_json(self):
json_str = self.read_string()
if json_str:
return json.loads(json_str)
else:
return None
def write_int(self, val):
data = pack('i', val)
sys.stdout.write(data)
sys.stdout.flush()
def write_string(self, val):
self.write_int(len(val))
sys.stdout.write(val)
sys.stdout.flush()
# log
def write_json(self, val):
s = json.dumps(val)
self.write_string(s)
def write_exception(self, e):
self.write_json(_convert_exception(e))
class FileObjectWithProgress(object):
"""
Readable file object with progress wrapper.
"""
def __init__(self, io):
"""
Wrap the underlying file object
:param file_obj: the file object to wrap
"""
self._io = io
self._file_obj = None
self._prev_process_size = 0
def __getattr__(self, attr):
return getattr(self._file_obj, attr)
def set_file_obj(self, file_obj):
self._file_obj = file_obj
self._prev_process_size = 0
def read(self, length=None):
read_data = self._file_obj.read(length)
self._prev_process_size += len(read_data)
res = {
'success': True,
'complete': False,
'uploaded': self._prev_process_size
}
if self._io:
self._io.write_json(res)
else:
print res
return read_data
def write(self, write_data):
self._file_obj.write(write_data)
self._prev_process_size += len(write_data)
res = {
'success': True,
'complete': False,
'downloaded': self._prev_process_size
}
if self._io:
self._io.write_json(res)
else:
print res
return None
def tell(self):
return self._file_obj.tell();
def seek(self, offset, whence=os.SEEK_SET):
self._file_obj.seek(offset, whence)
class DropboxStoreageApi(object):
def __init__(self, io=None):
self._file_obj_progress = FileObjectWithProgress(io)
access_token = os.environ.pop('DROPBOX_ACCESS_TOKEN', None)
refresh_token = os.environ.pop('DROPBOX_REFRESH_TOKEN', None)
client_id = os.environ.pop('DROPBOX_CLIENT_ID', None)
client_secret = os.environ.pop('DROPBOX_CLIENT_SECRET', None)
self.dropbox = dropbox.Dropbox(
oauth2_access_token=access_token,
oauth2_refresh_token=refresh_token,
app_key=client_id,
app_secret=client_secret
)
def metaData(self, in_json):
#syslog(LOG_ERR, "metaData: %s" % str(in_json))
path = in_json.get('path', None)
metadata = self.dropbox.files_get_metadata(path, include_media_info=False,
include_deleted=False, include_has_explicit_shared_members=False)
out_json = {
'success': True,
'Name': os.path.basename(metadata.path_display),
'Properties': _convert_properties(metadata),
}
#print out_json
return out_json
def createDir(self, in_json):
#print 'createDir:', in_json
path = in_json.get('path', None)
#print path
metadata = self.dropbox.files_create_folder(path)
out_json = {
'success': True,
'Name': os.path.basename(metadata.path_display),
'Properties': _convert_properties(metadata)
}
return out_json
def removeObject(self, in_json):
#print 'removeObject:', in_json
path = in_json.get('path', None)
#print path
metadata = self.dropbox.files_delete(path)
out_json = {
'success': True,
'Name': os.path.basename(metadata.path_display),
'Properties': _convert_properties(metadata)
}
return out_json
def getAccountInfo(self, in_json):
account = self.dropbox.users_get_current_account()
account_type = ""
team_id = ""
team_name = ""
if account.account_type.is_basic():
account_type = "basic"
elif account.account_type.is_business():
account_type = "business"
elif account.account_type.is_pro():
account_type = "pro"
if account.team is not None:
team_id = account.team.id
team_name = account.team.name
out_json = {
'success': True,
'name': account.name.display_name,
'account_id': account.account_id,
'account_type': account_type,
'disabled': account.disabled,
'email': account.email,
'email_verified': account.email_verified,
'country': account.country,
'is_paired': account.is_paired,
'locale': account.locale,
'team_id': team_id,
'team_name': team_name,
}
return out_json
def getSpaceInfo(self, in_json):
space = self.dropbox.users_get_space_usage()
#print space
individual_allocation = 0
team_allocation = 0
team_used = 0
if space.allocation.is_individual():
individual_allocation = space.allocation.get_individual().allocated
if space.allocation.is_team():
team_allocation = space.allocation.get_team().allocated
team_used = space.allocation.get_team().used
out_json = {
'success': True,
'individual_used': space.used,
'team_used': team_used,
'individual_allocation': individual_allocation,
'team_allocation': team_allocation
}
return out_json
def putFile(self, in_json):
#print 'in_json:', in_json
from_path = in_json.get('from_path')
to_path = in_json.get('to_path')
with open(from_path, "rb") as from_file:
metadata = self.dropbox.files_upload(from_file.read(), to_path, autorename=False, mode=WriteMode('overwrite'), mute=True)
#print 'Metadata:', metadata
out_json = {
'success': True,
'Name': os.path.basename(metadata.path_display),
'Properties': _convert_properties(metadata)
}
return out_json
def getFileRevisions(self, in_json):
path = in_json.get('path', None)
result = self.dropbox.files_list_revisions(path)
out_json = {
'success': True,
'Name': os.path.basename(path),
'entries': []
}
count = 0
for metadata in result.entries:
print metadata
if metadata is not None:
out_json['entries'].append({
'Properties': _convert_properties(metadata)
})
count += 1
out_json['count'] = count
#print out_json
return out_json
def getFileAndMeta(self, in_json):
from_path = in_json.get('from_path')
to_path = in_json.get('to_path')
rev = in_json.get('rev', None)
metadata = self.dropbox.files_download_to_file(to_path, from_path, rev)
#print 'Metadata:', metadata
out_json = {
'success': True,
'Name': os.path.basename(metadata.path_display),
'Properties': _convert_properties(metadata)
}
return out_json
def startChunk(self, in_json):
#print in_json
from_path = in_json.get('from_path')
length = int(in_json.get('length'))
with open(from_path, "rb") as from_file:
self._file_obj_progress.set_file_obj(from_file)
result = self.dropbox.files_upload_session_start(self._file_obj_progress.read(length))
new_offset = self._file_obj_progress.tell()
out_json = {
'success': True,
'upload_id': result.session_id,
'new_offset': new_offset
}
return out_json
def putChunk(self, in_json):
#print in_json
from_path = in_json.get('from_path')
length = int(in_json.get('length'))
offset = int(in_json.get('offset', 0))
upload_id = in_json.get('upload_id', None)
#print "off_set:",offset, " upload_id:", upload_id
with open(from_path, "rb") as from_file:
self._file_obj_progress.set_file_obj(from_file)
self._file_obj_progress.seek(offset)
self.dropbox.files_upload_session_append_v2(self._file_obj_progress.read(length),
UploadSessionCursor(upload_id, offset))
new_offset = self._file_obj_progress.tell()
out_json = {
'success': True,
'upload_id': upload_id,
'new_offset': new_offset
}
return out_json
def commitChunks(self, in_json):
#print in_json
from_path = in_json.get('from_path')
to_path = in_json.get('to_path')
offset = int(in_json.get('offset', 0))
length = int(in_json.get('length'))
upload_id = in_json.get('upload_id')
commitInfo = dropbox.files.CommitInfo(path=to_path, mode=WriteMode('overwrite'), mute=True)
with open(from_path, "rb") as from_file:
self._file_obj_progress.set_file_obj(from_file)
self._file_obj_progress.seek(offset)
metadata = self.dropbox.files_upload_session_finish(self._file_obj_progress.read(length),
UploadSessionCursor(upload_id, offset),
commitInfo)
out_json = {
'success': True,
'Name': os.path.basename(metadata.path_display),
'Properties': _convert_properties(metadata)
}
return out_json
def listFolder(self, in_json):
#syslog(LOG_ERR, "listFolder: %s" % str(in_json))
#print in_json
recursive = in_json.get('recursive', False)
path = in_json.get('path', '')
result = self.dropbox.files_list_folder(path, recursive)
#print result
count = 0
out_json = {
'success': True,
'cursor': result.cursor,
'has_more': result.has_more,
'entries': []
}
#if not exist metadata is none, return count = 0
for metadata in result.entries:
if metadata is not None:
out_json['entries'].append({
'Properties': _convert_properties(metadata)
})
count += 1
out_json['count'] = count
#print out_json
return out_json
def listFolderContinue(self, in_json):
#syslog(LOG_ERR, "listFolderContinue: %s" % str(in_json))
#print in_json
cursor = in_json.get('cursor', None)
result = self.dropbox.files_list_folder_continue(cursor)
#print result
count = 0
out_json = {
'success': True,
'cursor': result.cursor,
'has_more': result.has_more,
'entries': []
}
#if not exist metadata is none, return count = 0
for metadata in result.entries:
if metadata is not None:
out_json['entries'].append({
'Properties': _convert_properties(metadata)
})
count += 1
out_json['count'] = count
#print out_json
return out_json
def start_server():
io = SimpleIO()
try:
api = DropboxStoreageApi(io)
except Exception as e:
io.write_exception(e)
return False
io.write_string('start')
while True:
try:
in_json = io.read_json()
fn_name = in_json['fn']
fn = getattr(api, fn_name)
del in_json['fn']
if fn is None:
raise SystemError('no such fn: ' + fn_name)
#log_debug('\033[34mexecute: ' + fn_name + ' ' + json.dumps(in_json) + '\033[0m');
res = fn(in_json)
io.write_json(res)
except StopIteration:
break
except Exception as e:
io.write_exception(e)
continue
if __name__ == '__main__':
res = start_server()
sys.exit(0 if res else 1)