예제 #1
0
    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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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()
예제 #6
0
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)
예제 #7
0
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

        """
예제 #8
0
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()
예제 #9
0
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()
예제 #10
0
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
예제 #11
0
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)
예제 #12
0
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
예제 #13
0
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
예제 #14
0
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])