def get_program(self): """Retrieve a program file from the Mpala Tower Dropbox listings.""" # Must use Dropbox to get program files. from dropbox import Dropbox from posixpath import join import os # Set up the Dropbox connection. Not sure how access_tokens will work access_token = os.environ.get('access_token') dropbox_dir = os.environ.get('dropbox_dir') client = Dropbox(access_token) # If this is our first time with this file, set the program name and # location. self.program_location = join( dropbox_dir, program_location, self.program_name ) # Retrieve the REST object from Dropbox prog_link = client.files_get_temporary_link(self.program_location) response = requests.get(prog_link.link) # Put the program file contents into an array for parsing program_content = response.text # Send that stuff back. return program_content
class DropBoxDataProvider(DataProviderBase): smoke_url = DROPBOX_SMOKE_URL def __init__(self, acs_token): self.dbx = Dropbox(acs_token) def api_smoke(self) -> int: return len(self.dbx.files_list_folder('').entries) def get_list_of_objects(self, dbx_folder='') -> list: result = namedtuple('Result', ['filename', 'filepatch']) return [ result(el.name, el.path_lower) for el in self.dbx.files_list_folder(dbx_folder).entries ] def file_delete(self, dbx_file) -> str: return self.dbx.files_delete_v2(dbx_file).metadata.path_lower def file_download(self, local_file, dbx_file) -> str: return self.dbx.files_download_to_file(local_file, dbx_file).path_lower def file_upload(self, local_file, dbx_file) -> str: if isinstance(local_file, str): if local_file.startswith("https://"): waiting_time = 0.1 waiting_attempt = 100 url_result = self.dbx.files_save_url(dbx_file, local_file) job_id = url_result.get_async_job_id() while waiting_attempt > 0: st = self.dbx.files_save_url_check_job_status(job_id) if st.is_complete(): return st.get_complete().path_lower sleep(waiting_time) waiting_attempt -= 1 else: with open(local_file, 'rb') as f: return self.dbx.files_upload( f.read(), dbx_file, autorename=True, strict_conflict=True).path_lower else: return self.dbx.files_upload(local_file.read(), dbx_file, autorename=True, strict_conflict=True).path_lower def file_move(self, dbx_file_from, dbx_file_to) -> str: return self.dbx.files_move_v2(dbx_file_from, dbx_file_to).metadata.path_lower def create_folder(self, dbx_folder) -> str: return self.dbx.files_create_folder_v2(dbx_folder).metadata.path_lower def get_file_tmp_link(self, dbx_path) -> str: return self.dbx.files_get_temporary_link(dbx_path).link
class DropBoxStorage(Storage): """ The default Storage base for all file storing of the Chat app """ def __init__(self, oauth2_access_token: str = None, root_path: str = None): """ The access token and root path may be provided here as well, if they are not provided here, program will check settings for environment variables :param oauth2_access_token: The OAUTH2 access token for the DropBox api :param root_path: The root path for storing the files in the DropBox storage, defaults '/' """ oauth2_access_token = oauth2_access_token or settings.DROPBOX_OAUTH2_TOKEN self.root_path = root_path or settings.DROPBOX_ROOT_PATH or '/' if oauth2_access_token is None: raise ImproperlyConfigured( "You must configure an OATH2 access token ENV named " "'DROPBOX_OAUTH2_TOKEN'.") self.client = Dropbox(oauth2_access_token) def delete(self, name: str): """ Deletes the specified file from the storage system. """ self.client.files_delete_v2(join(self.root_path, basename(name))) def exists(self, name: str): """ Returns True if a file referenced by the given name already exists in the storage system, or False if the name is available for a new file. """ try: return bool( self.client.files_get_metadata( join(self.root_path, basename(name)))) except ApiError: return False def url(self, name: str): """ Returns an absolute URL where the file's contents can be accessed directly by a Web browser. """ media = self.client.files_get_temporary_link( join(self.root_path, basename(name))) return media.link def _open(self, name: str, mode: str = 'rb'): """ Call DropBoxStorage.open(...) instead """ file = DropBoxFile(join(self.root_path, basename(name)), self.client) return file def _save(self, name: str, content: File): """ Call DropBoxStorage.save(...) instead """ self.client.files_upload(content.read(), join(self.root_path, basename(name))) return name
class DropboxStorage(Storage): """ A storage class providing access to resources in a Dropbox folder. """ def __init__(self, token=ACCESS_TOKEN, location=ROOT_FOLDER): if not token: raise ImproperlyConfigured("You must configure an access token at " "'settings.DROPBOX_ACCESS_TOKEN'.") self.client = Dropbox(token) self.account_info = self.client.users_get_current_account() self.location = location or DEFAULT_ROOT_FOLDER self.base_url = 'https://dl.dropboxusercontent.com/' def _get_abs_path(self, name): return os.path.realpath(os.path.join(self.location, name)) def _open(self, name, mode='rb'): name = self._get_abs_path(name) remote_file = DropboxFile(name, self, mode=mode) return remote_file def _save(self, name, content): name = self._get_abs_path(name) directory = os.path.dirname(name) if not self.exists(directory) and directory: self.client.files_create_folder(directory) # response = self.client.files_get_metadata(directory) # if not response['is_dir']: # raise IOError("%s exists and is not a directory." % directory) abs_name = os.path.realpath(os.path.join(self.location, name)) self.client.files_upload(content.read(), abs_name) return name def delete(self, name): name = self._get_abs_path(name) try: self.client.files_delete(name) except ApiError as e: if isinstance(e.error, DeleteError)\ and e.error.is_path_lookup()\ and e.error.get_path_lookup().is_not_found(): # not found return False # error raise e # deleted return True def exists(self, name): name = self._get_abs_path(name) try: self.client.files_get_metadata(name) except ApiError as e: if hasattr(e.error, 'is_path')\ and e.error.is_path()\ and e.error.get_path().is_not_found(): # not found return False # error raise e # found return True def listdir(self, path): path = self._get_abs_path(path) response = self.client.files_list_folder(path) directories = [] files = [] for entry in response.entries: if isinstance(entry, FolderMetadata): directories.append(os.path.basename(entry.path_display)) elif isinstance(entry, FileMetadata): files.append(os.path.basename(entry.path_display)) return directories, files def size(self, name): name = self._get_abs_path(name) return self.client.files_get_metadata(name).size def url(self, name): name = self._get_abs_path(name) return self.client.files_get_temporary_link(name).link def modified_time(self, name): name = self._get_abs_path(name) return self.client.files_get_metadata(name).server_modified def accessed_time(self, name): name = self._get_abs_path(name) # Note to the unwary, this is actually an mtime return self.client.files_get_metadata(name).client_modified def get_available_name(self, name, max_length=None): """ Returns a filename that's free on the target storage system, and available for new content to be written to. """ name = self._get_abs_path(name) dir_name, file_name = os.path.split(name) file_root, file_ext = os.path.splitext(file_name) # If the filename already exists, add an underscore and a number (before # the file extension, if one exists) to the filename until the generated # filename doesn't exist. count = itertools.count(1) while self.exists(name): # file_ext includes the dot. _fn = "%s_%s%s" % (file_root, count.next(), file_ext) name = os.path.join(dir_name, _fn) return name
class DropBoxStorage(Storage): """DropBox Storage class for Django pluggable storage system.""" CHUNK_SIZE = 4 * 1024 * 1024 def __init__(self, oauth2_access_token=None, root_path=None): oauth2_access_token = oauth2_access_token or setting('DROPBOX_OAUTH2_TOKEN') self.root_path = root_path or setting('DROPBOX_ROOT_PATH', '/') if oauth2_access_token is None: raise ImproperlyConfigured("You must configure a token auth at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.client = Dropbox(oauth2_access_token) def _full_path(self, name): if name == '/': name = '' return safe_join(self.root_path, name).replace('\\', '/') def delete(self, name): self.client.files_delete(self._full_path(name)) def exists(self, name): try: return bool(self.client.files_get_metadata(self._full_path(name))) except ApiError: return False def listdir(self, path): directories, files = [], [] full_path = self._full_path(path) metadata = self.client.files_get_metadata(full_path) for entry in metadata['contents']: entry['path'] = entry['path'].replace(full_path, '', 1) entry['path'] = entry['path'].replace('/', '', 1) if entry['is_dir']: directories.append(entry['path']) else: files.append(entry['path']) return directories, files def size(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata['bytes'] def modified_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) mod_time = datetime.strptime(metadata['modified'], DATE_FORMAT) return mod_time def accessed_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) acc_time = datetime.strptime(metadata['client_mtime'], DATE_FORMAT) return acc_time def url(self, name): media = self.client.files_get_temporary_link(self._full_path(name)) return media.link def _open(self, name, mode='rb'): remote_file = DropBoxFile(self._full_path(name), self) return remote_file def _save(self, name, content): content.open() if content.size <= self.CHUNK_SIZE: self.client.files_upload(content.read(), self._full_path(name)) else: self._chunked_upload(content, self._full_path(name)) content.close() return name def _chunked_upload(self, content, dest_path): upload_session = self.client.files_upload_session_start( content.read(self.CHUNK_SIZE) ) cursor = UploadSessionCursor( session_id=upload_session.session_id, offset=content.tell() ) commit = CommitInfo(path=dest_path) while content.tell() < content.size: if (content.size - content.tell()) <= self.CHUNK_SIZE: self.client.files_upload_session_finish( content.read(self.CHUNK_SIZE), cursor, commit ) else: self.client.files_upload_session_append_v2( content.read(self.CHUNK_SIZE), cursor ) cursor.offset = content.tell()
class DropBoxStorage(Storage): """DropBox Storage class for Django pluggable storage system.""" location = setting('DROPBOX_ROOT_PATH', '/') oauth2_access_token = setting('DROPBOX_OAUTH2_TOKEN') timeout = setting('DROPBOX_TIMEOUT', _DEFAULT_TIMEOUT) write_mode = setting('DROPBOX_WRITE_MODE', _DEFAULT_MODE) CHUNK_SIZE = 4 * 1024 * 1024 def __init__(self, oauth2_access_token=oauth2_access_token, root_path=location, timeout=timeout, write_mode=write_mode): if oauth2_access_token is None: raise ImproperlyConfigured("You must configure an auth token at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.root_path = root_path self.write_mode = write_mode self.client = Dropbox(oauth2_access_token, timeout=timeout) def _full_path(self, name): if name == '/': name = '' # If the machine is windows do not append the drive letter to file path if os.name == 'nt': final_path = os.path.join(self.root_path, name).replace('\\', '/') # Separator on linux system sep = '//' base_path = self.root_path if (not os.path.normcase(final_path).startswith(os.path.normcase(base_path + sep)) and os.path.normcase(final_path) != os.path.normcase(base_path) and os.path.dirname(os.path.normcase(base_path)) != os.path.normcase(base_path)): raise SuspiciousFileOperation( 'The joined path ({}) is located outside of the base path ' 'component ({})'.format(final_path, base_path)) return final_path else: return safe_join(self.root_path, name).replace('\\', '/') def delete(self, name): self.client.files_delete(self._full_path(name)) def exists(self, name): try: return bool(self.client.files_get_metadata(self._full_path(name))) except ApiError: return False def listdir(self, path): directories, files = [], [] full_path = self._full_path(path) if full_path == '/': full_path = '' metadata = self.client.files_list_folder(full_path) for entry in metadata.entries: if isinstance(entry, FolderMetadata): directories.append(entry.name) else: files.append(entry.name) return directories, files def size(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.size def modified_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.server_modified def accessed_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.client_modified def url(self, name): media = self.client.files_get_temporary_link(self._full_path(name)) return media.link def _open(self, name, mode='rb'): remote_file = DropBoxFile(self._full_path(name), self) return remote_file def _save(self, name, content): content.open() if content.size <= self.CHUNK_SIZE: self.client.files_upload(content.read(), self._full_path(name), mode=WriteMode(self.write_mode)) else: self._chunked_upload(content, self._full_path(name)) content.close() return name def _chunked_upload(self, content, dest_path): upload_session = self.client.files_upload_session_start( content.read(self.CHUNK_SIZE) ) cursor = UploadSessionCursor( session_id=upload_session.session_id, offset=content.tell() ) commit = CommitInfo(path=dest_path, mode=WriteMode(self.write_mode)) while content.tell() < content.size: if (content.size - content.tell()) <= self.CHUNK_SIZE: self.client.files_upload_session_finish( content.read(self.CHUNK_SIZE), cursor, commit ) else: self.client.files_upload_session_append_v2( content.read(self.CHUNK_SIZE), cursor ) cursor.offset = content.tell() def get_available_name(self, name, max_length=None): """Overwrite existing file with the same name.""" name = self._full_path(name) if self.write_mode == 'overwrite': return get_available_overwrite_name(name, max_length) return super().get_available_name(name, max_length)
class DropboxStorage(Storage): """ A storage class providing access to resources in a Dropbox Public folder. """ def __init__(self, location='/Public'): self.client = Dropbox(ACCESS_TOKEN) self.account_info = self.client.users_get_current_account() self.location = location self.base_url = 'https://dl.dropboxusercontent.com/' def _get_abs_path(self, name): return os.path.realpath(os.path.join(self.location, name)) def _open(self, name, mode='rb'): name = self._get_abs_path(name) remote_file = DropboxFile(name, self, mode=mode) return remote_file def _save(self, name, content): name = self._get_abs_path(name) directory = os.path.dirname(name) if not self.exists(directory) and directory: self.client.files_create_folder(directory) # response = self.client.files_get_metadata(directory) # if not response['is_dir']: # raise IOError("%s exists and is not a directory." % directory) abs_name = os.path.realpath(os.path.join(self.location, name)) foo = self.client.files_upload(content.read(), abs_name) return name def delete(self, name): name = self._get_abs_path(name) self.client.files_delete(name) def exists(self, name): name = self._get_abs_path(name) try: self.client.files_get_metadata(name) except ApiError as e: if e.error.is_path() and e.error.get_path().is_not_found(): # not found return False raise e return True def listdir(self, path): path = self._get_abs_path(path) response = self.client.files_list_folder(path) directories = [] files = [] for entry in response.entries: if type(entry) == FolderMetadata: directories.append(os.path.basename(entry.path_display)) elif type(entry) == FileMetadata: files.append(os.path.basename(entry.path_display)) return directories, files def size(self, name): cache_key = 'django-dropbox-size:{}'.format(filepath_to_uri(name)) size = cache.get(cache_key) if not size: size = self.client.files_get_metadata(name).size cache.set(cache_key, size, CACHE_TIMEOUT) return size def url(self, name): if name.startswith(self.location): name = name[len(self.location) + 1:] name = os.path.basename(self.location) + "/" + name if self.base_url is None: raise ValueError("This file is not accessible via a URL.") myurl = urlparse.urljoin(self.base_url, filepath_to_uri(name)) if "static" not in self.location: # Use a dynamic URL for "non-static" files. try: new_name = os.path.dirname(self.location) + "/" + name fp = filepath_to_uri(new_name) cache_key = 'django-dropbox-size:{}'.format(fp) myurl = cache.get(cache_key) if not myurl: try: shared_link = self.client.sharing_create_shared_link(fp) myurl = shared_link.url + '&raw=1' logger.debug("shared link: {0}, myurl: {1}".format(shared_link, myurl)) except Exception,e: logger.exception(e) if myurl is None: temp_link = self.client.files_get_temporary_link(fp) myurl = temp_link.link logger.debug("temp link: {0}, myurl: {1}".format(temp_link, myurl)) cache.set(cache_key, myurl, SHARE_LINK_CACHE_TIMEOUT) except Exception,e: logger.exception(e) return myurl """
class DropBoxStorage(Storage): """DropBox Storage class for Django pluggable storage system.""" CHUNK_SIZE = 4 * 1024 * 1024 def __init__(self, oauth2_access_token=None, root_path=None): oauth2_access_token = oauth2_access_token or setting( 'DROPBOX_OAUTH2_TOKEN') self.root_path = root_path or setting('DROPBOX_ROOT_PATH', '/') if oauth2_access_token is None: raise ImproperlyConfigured("You must configure a token auth at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.client = Dropbox(oauth2_access_token) def _full_path(self, path): path = PurePosixPath(self.root_path) / path path = str(path) if path == '/': path = '' return path def delete(self, name): self.client.files_delete(self._full_path(name)) def exists(self, name): try: return bool(self.client.files_get_metadata(self._full_path(name))) except ApiError: return False def listdir(self, path): directories, files = [], [] full_path = self._full_path(path) result = self.client.files_list_folder(full_path) for entry in result.entries: if isinstance(entry, FolderMetadata): directories.append(entry.name) else: files.append(entry.name) assert not result.has_more, "FIXME: Not implemented!" return directories, files def size(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.size def modified_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.server_modified def accessed_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) # Note to the unwary, this is actually an mtime return metadata.client_modified def url(self, name): try: media = self.client.files_get_temporary_link(self._full_path(name)) return media.link except ApiError: raise ValueError("This file is not accessible via a URL.") def _open(self, name, mode='rb'): return DropBoxFile(self._full_path(name), self) def _save(self, name, content): try: content.open() if content.size <= self.CHUNK_SIZE: self.client.files_upload(content.read(), self._full_path(name)) else: self._chunked_upload(content, self._full_path(name)) finally: content.close() return name def _chunked_upload(self, content, dest_path): upload_session = self.client.files_upload_session_start( content.read(self.CHUNK_SIZE)) cursor = UploadSessionCursor(session_id=upload_session.session_id, offset=content.tell()) commit = CommitInfo(path=dest_path) while content.tell() < content.size: if (content.size - content.tell()) <= self.CHUNK_SIZE: self.client.files_upload_session_finish( content.read(self.CHUNK_SIZE), cursor, commit) else: self.client.files_upload_session_append_v2( content.read(self.CHUNK_SIZE), cursor) cursor.offset = content.tell()
class DropBoxStorage(Storage): """DropBox Storage class for Django pluggable storage system.""" CHUNK_SIZE = 4 * 1024 * 1024 def __init__(self, oauth2_access_token=None, root_path=None, timeout=None): oauth2_access_token = oauth2_access_token or setting( 'DROPBOX_OAUTH2_TOKEN') if oauth2_access_token is None: raise ImproperlyConfigured("You must configure an auth token at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.root_path = root_path or setting('DROPBOX_ROOT_PATH', '/') timeout = timeout or setting('DROPBOX_TIMEOUT', _DEFAULT_TIMEOUT) self.client = Dropbox(oauth2_access_token, timeout=timeout) def _full_path(self, name): if name == '/': name = '' return safe_join(self.root_path, name).replace('\\', '/') def delete(self, name): self.client.files_delete(self._full_path(name)) def exists(self, name): try: return bool(self.client.files_get_metadata(self._full_path(name))) except ApiError: return False def listdir(self, path): directories, files = [], [] full_path = self._full_path(path) if full_path == '/': full_path = '' metadata = self.client.files_list_folder(full_path) for entry in metadata.entries: if isinstance(entry, FolderMetadata): directories.append(entry.name) else: files.append(entry.name) return directories, files def size(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.size def modified_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.server_modified def accessed_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata.client_modified def url(self, name): media = self.client.files_get_temporary_link(self._full_path(name)) return media.link def _open(self, name, mode='rb'): remote_file = DropBoxFile(self._full_path(name), self) return remote_file def _save(self, name, content): content.open() if content.size <= self.CHUNK_SIZE: self.client.files_upload(content.read(), self._full_path(name)) else: self._chunked_upload(content, self._full_path(name)) content.close() return name def _chunked_upload(self, content, dest_path): upload_session = self.client.files_upload_session_start( content.read(self.CHUNK_SIZE)) cursor = UploadSessionCursor(session_id=upload_session.session_id, offset=content.tell()) commit = CommitInfo(path=dest_path) while content.tell() < content.size: if (content.size - content.tell()) <= self.CHUNK_SIZE: self.client.files_upload_session_finish( content.read(self.CHUNK_SIZE), cursor, commit) else: self.client.files_upload_session_append_v2( content.read(self.CHUNK_SIZE), cursor) cursor.offset = content.tell()
class DropBoxStorage(Storage): """DropBox Storage class for Django pluggable storage system.""" def __init__(self, oauth2_access_token=None, root_path=None): oauth2_access_token = oauth2_access_token or setting( 'DROPBOX_OAUTH2_TOKEN') self.root_path = root_path or setting('DROPBOX_ROOT_PATH', '/') if oauth2_access_token is None: raise ImproperlyConfigured("You must configure a token auth at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.client = Dropbox(oauth2_access_token) def _full_path(self, name): if name == '/': name = '' return safe_join(self.root_path, name).replace('\\', '/') def delete(self, name): self.client.files_delete(self._full_path(name)) def exists(self, name): try: return bool(self.client.files_get_metadata(self._full_path(name))) except ApiError: return False def listdir(self, path): directories, files = [], [] full_path = self._full_path(path) metadata = self.client.files_get_metadata(full_path) for entry in metadata['contents']: entry['path'] = entry['path'].replace(full_path, '', 1) entry['path'] = entry['path'].replace('/', '', 1) if entry['is_dir']: directories.append(entry['path']) else: files.append(entry['path']) return directories, files def size(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata['bytes'] def modified_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) mod_time = datetime.strptime(metadata['modified'], DATE_FORMAT) return mod_time def accessed_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) acc_time = datetime.strptime(metadata['client_mtime'], DATE_FORMAT) return acc_time def url(self, name): media = self.client.files_get_temporary_link(self._full_path(name)) return media['link'] def _open(self, name, mode='rb'): remote_file = DropBoxFile(self._full_path(name), self) return remote_file def _save(self, name, content): self.client.files_upload(content, self._full_path(name)) return name
class DropboxUploader(BaseUploader): def __init__(self): super(BaseUploader, self).__init__() self.oauth2_access_token = os.getenv( "DROPBOX_OAUTH2_TOKEN") or get_app_config("DROPBOX_OAUTH2_TOKEN") self.root_path = (os.getenv("DROPBOX_ROOT_PATH") or get_app_config("DROPBOX_ROOT_PATH") or "/CTFd") self.client = Dropbox(self.oauth2_access_token, timeout=100) self.write_mode = "add" # can be set to overwrite def _clean_filename(self, c): if c in string.ascii_letters + string.digits + "-" + "_" + ".": return True def _full_path(self, name): return safe_join(self.root_path, name).replace("\\", "/") def store(self, fileobj, filename): self.client.files_upload(fileobj.read(), self._full_path(filename), mode=WriteMode(self.write_mode)) return filename def upload(self, file_obj, filename): filename = filter(self._clean_filename, secure_filename(filename).replace(" ", "_")) filename = "".join(filename) if len(filename) <= 0: return False md5hash = hexencode(os.urandom(16)) dst = md5hash + "/" + filename self.store(file_obj, dst) return dst def download(self, filename): media = self.client.files_get_temporary_link(self._full_path(filename)) print(media.link) return redirect(media.link) def delete(self, filename): directory = os.path.dirname(self._full_path(filename)) self.client.files_delete(directory) return True def sync(self): local_folder = current_app.config.get("UPLOAD_FOLDER") root_metadata = self.client.files_list_folder(self.root_path) for folder_entry in root_metadata.entries: if isinstance(folder_entry, FolderMetadata): filemetadata = self.client.files_list_folder( folder_entry.path_lower) for file_entry in filemetadata.entries: if not isinstance(file_entry, FolderMetadata): dropbox_path = file_entry.path_lower.replace( self.root_path.lower() + "/", "") local_path = os.path.join(local_folder, dropbox_path) directory = os.path.dirname(local_path) if not os.path.exists(directory): os.makedirs(directory) self.client.files_download_to_file( local_path, file_entry.path_lower)
class DropboxStorage(Storage): """ A storage class providing access to resources in a Dropbox Public folder. """ def __init__(self, location='/Public'): self.client = Dropbox(ACCESS_TOKEN) self.account_info = self.client.users_get_current_account() self.location = location self.base_url = 'https://dl.dropboxusercontent.com/' def _get_abs_path(self, name): return os.path.realpath(os.path.join(self.location, name)) def _open(self, name, mode='rb'): name = self._get_abs_path(name) remote_file = DropboxFile(name, self, mode=mode) return remote_file def _save(self, name, content): name = self._get_abs_path(name) directory = os.path.dirname(name) if not self.exists(directory) and directory: self.client.files_create_folder(directory) # response = self.client.files_get_metadata(directory) # if not response['is_dir']: # raise IOError("%s exists and is not a directory." % directory) abs_name = os.path.realpath(os.path.join(self.location, name)) foo = self.client.files_upload(content.read(), abs_name) return name def delete(self, name): name = self._get_abs_path(name) self.client.files_delete(name) def exists(self, name): name = self._get_abs_path(name) try: self.client.files_get_metadata(name) except ApiError as e: if e.error.is_path() and e.error.get_path().is_not_found( ): # not found return False raise e return True def listdir(self, path): path = self._get_abs_path(path) response = self.client.files_list_folder(path) directories = [] files = [] for entry in response.entries: if type(entry) == FolderMetadata: directories.append(os.path.basename(entry.path_display)) elif type(entry) == FileMetadata: files.append(os.path.basename(entry.path_display)) return directories, files def size(self, name): cache_key = 'django-dropbox-size:{}'.format(filepath_to_uri(name)) size = cache.get(cache_key) if not size: size = self.client.files_get_metadata(name).size cache.set(cache_key, size, CACHE_TIMEOUT) return size def url(self, name): cache_key = 'django-dropbox-size:{}'.format(filepath_to_uri(name)) url = cache.get(cache_key) if not url: url = self.client.files_get_temporary_link(name).link cache.set(cache_key, url, SHARE_LINK_CACHE_TIMEOUT) return url def get_available_name(self, name): """ Returns a filename that's free on the target storage system, and available for new content to be written to. """ name = self._get_abs_path(name) dir_name, file_name = os.path.split(name) file_root, file_ext = os.path.splitext(file_name) # If the filename already exists, add an underscore and a number (before # the file extension, if one exists) to the filename until the generated # filename doesn't exist. count = itertools.count(1) while self.exists(name): # file_ext includes the dot. name = os.path.join( dir_name, "%s_%s%s" % (file_root, count.next(), file_ext)) return name
class DropBoxStorage(Storage): """DropBox Storage class for Django pluggable storage system.""" def __init__(self, oauth2_access_token=None, root_path=None): oauth2_access_token = oauth2_access_token or setting('DROPBOX_OAUTH2_TOKEN') self.root_path = root_path or setting('DROPBOX_ROOT_PATH', '/') if oauth2_access_token is None: raise ImproperlyConfigured("You must configure a token auth at" "'settings.DROPBOX_OAUTH2_TOKEN'.") self.client = Dropbox(oauth2_access_token) def _full_path(self, name): if name == '/': name = '' return safe_join(self.root_path, name).replace('\\', '/') def delete(self, name): self.client.files_delete(self._full_path(name)) def exists(self, name): try: return bool(self.client.files_get_metadata(self._full_path(name))) except ApiError: return False def listdir(self, path): directories, files = [], [] full_path = self._full_path(path) metadata = self.client.files_get_metadata(full_path) for entry in metadata['contents']: entry['path'] = entry['path'].replace(full_path, '', 1) entry['path'] = entry['path'].replace('/', '', 1) if entry['is_dir']: directories.append(entry['path']) else: files.append(entry['path']) return directories, files def size(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) return metadata['bytes'] def modified_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) mod_time = datetime.strptime(metadata['modified'], DATE_FORMAT) return mod_time def accessed_time(self, name): metadata = self.client.files_get_metadata(self._full_path(name)) acc_time = datetime.strptime(metadata['client_mtime'], DATE_FORMAT) return acc_time def url(self, name): media = self.client.files_get_temporary_link(self._full_path(name)) return media.link def _open(self, name, mode='rb'): remote_file = DropBoxFile(self._full_path(name), self) return remote_file def _save(self, name, content): self.client.files_upload(content, self._full_path(name)) return name
class DropboxStorage: def __init__(self): """Initialize the class object with attribute only for internal use.""" self._APP_KEY = 'orl3775x8jdgcg0' self._APP_SECRET = 'cgz8tvz8k4uiubx' self._dbx_user_account = None self._access_token = None @property def access_token(self): """Return reference to the only internal attribute""" return self._access_token @property def dbx_user_account(self): """Return user's Dropbox account information""" return self._dbx_user_account.users_get_current_account() def link_account(self): """Link user's Dropbox storage, in case of failure return False, indicating that the error occurred.""" auth_flow = DropboxOAuth2FlowNoRedirect(self._APP_KEY, self._APP_SECRET) authorize_url = auth_flow.start() print("You will be redirected to the authorization page.") print("Copy the authorization code and paste it to the terminal window.") time.sleep(3) webbrowser.open(authorize_url) auth_code = input("Enter the code: ").strip() try: oauth_result = auth_flow.finish(auth_code) self._access_token = oauth_result.access_token self._dbx_user_account = Dropbox(self._access_token) return True except: print( "An error occurred while connecting Dropbox storage.\nPlease, check you internet connection and try again.") return False def unlink_account(self): """Delete user's access tokens""" self._access_token = None self._dbx_user_account = None return True def upload_file(self, local_file, backup_path): """Upload file to the path, specified by backup_path argument, in case of failure write the message to the stdout.""" try: with open(local_file, mode='rb') as f: try: self._dbx_user_account.files_upload(f.read(), backup_path, mode=WriteMode('overwrite')) return True except ApiError as err: print("Error occurred while uploading file to Dropbox.") except: print("Error occurred while opening local file.") def delete_file(self, filename): """Delete a file in the user's Dropbox storage""" try: self._dbx_user_account.files_delete_v2(self.search(filename)) return True except Exception: print("File wasn't found in Dropbox.") def sync(self, local_path): """Update the file in the user's Dropbox storage, if file wasn't found, write the message to the stdout.""" try: backup_path = self.search(local_path.split('/')[-1]) if '/' == local_path[0]: local_path = local_path[1:] self.upload_file(local_path, backup_path) print("Synchronized with Dropbox.") except: print("Failed to synchronize file with Dropbox.") def search(self, query_name): """Return the path to file if it was found in the user's Dropbox storage, otherwise return False, indicating that file wasn't found.""" lst = [i.path_display for i in self._dbx_user_account.files_list_folder('', recursive=True).entries if query_name in i.path_display] if len(lst) > 0: return lst[0] else: return False def download_file(self, filename): """Open a link to download a file from the user's Dropbox storage, in case of failure returns False.""" try: temp_file = self._dbx_user_account.files_get_temporary_link(self.search(filename)) webbrowser.open(temp_file.link) except: return False def list_files(self): """Write to the stdout the list of all files in the user's Dropbox storage.""" for i in self._dbx_user_account.files_list_folder('', recursive=True).entries: print(i.path_display.split('/')[-1])