Пример #1
0
    def upload_folder(self,
                      local_file_folder: str,
                      remote_file_folder: str = None):

        lfpp = FilePathParser(full_path_file_string=local_file_folder)
        if is_blank(lfpp.source_path):
            raise DropboxAPIException(
                message="#upload_folder , local file folder is blank !")
        if not os.path.exists(lfpp.source_path):
            raise DropboxAPIException(
                message="#upload_folder , local file folder is not exist !")
        if not os.path.isdir(lfpp.source_path):
            raise DropboxAPIException(
                message="#upload_folder , local file folder is not folder !")

        if is_not_blank(remote_file_folder):
            remote_file_folder = DROPBOX_FILE_SEP + remote_file_folder if not remote_file_folder.startswith(
                DROPBOX_FILE_SEP) else remote_file_folder
            remote_file_folder = remote_file_folder + DROPBOX_FILE_SEP if not remote_file_folder.endswith(
                DROPBOX_FILE_SEP) else remote_file_folder

        def gen_local_file_path(folder: str):
            global roots, dirs
            for roots, dirs, files in os.walk(top=folder):
                for _file in files:
                    local_file_path = os.path.join(roots, _file)
                    _f = FilePathParser(full_path_file_string=local_file_path)
                    remote_file_path = _f.translate_to_linux_file()
                    yield local_file_path, remote_file_path, _f.source_name

            if len(dirs) > 0:
                for _dir in dirs:
                    local_folder_path = os.path.join(roots, _dir)
                    gen_local_file_path(folder=local_folder_path)

        for glfp in gen_local_file_path(folder=local_file_folder):
            _local_file_path = glfp[0]
            _remote_file_path = glfp[1]
            _source_file_name = glfp[2]
            if is_not_blank(remote_file_folder):
                _remote_file_path = os.path.join(remote_file_folder,
                                                 _source_file_name)

            if is_debug():
                logger.debug("%s ==> %s " %
                             (_local_file_path, _remote_file_path))
            # md = self.upload(local_file_path=_local_file_path, remote_file_path=_remote_file_path)
            # print(md)
            future = upload_file_pool.submit(
                fn=self.upload,
                local_file_path=_local_file_path,
                remote_file_path=_remote_file_path)

        pass
Пример #2
0
 def download_as_bytes(self, remote_file_path: str) -> bytes:
     """
     download as bytes
     remote file path is not blank
     :param remote_file_path:        remote file path in dropbox
     :return:                        byte array
     """
     assert is_not_blank(remote_file_path)
     return self.download_as_response(
         remote_file_path=remote_file_path).content
Пример #3
0
 def download_as_response(self, remote_file_path: str) -> Response:
     """
     download as response
     remote file path is not blank
     :param remote_file_path:        remote file path in dropbox
     :return:                        requests.Response
     """
     assert is_not_blank(remote_file_path)
     _, response = self.async_download_from_dropbox(
         remote_file_path=remote_file_path)
     return response
Пример #4
0
    def download_as_file(
        self,
        remote_file_path: str,
        local_file_path: str,
        excepted_name: str,
    ) -> SimpleFileMetadata:
        """
        download as local file
        # if `remote_file_path` not start with `/` , and combine `/` to head;
        # sample as  `foo/bar.jpg` to `/foo/bar.jpg`

        # if source name not in remote file path , throw `DropboxAPIException`
        # if source name not in local file path ,  first fetch excepted name , second fetch local source name
        # sample as
            remote_file_path = "/foo/bar.jpg"       local_path_path="/local/    => "/local/bar.jpg"

        # if excepted name exist , replace source name to excepted name.
        # sample as
            excepted_name = "cat.jpg" ,         local_path_file = "/local/bar.jpg" => "/local/cat.jpg"
            excepted_name = "/animal/cat.jpg" , local_path_file = "/local/bar.jpg" => "/local/cat.jpg"

        usage:
            >>> self.download_as_file(remote_file_path="foo/bar.jpg",local_file_path="/local/bar.jpg",excepted_name="cat.jpg")
            >>> self.download_as_file(remote_file_path="/foo/bar.jpg",local_file_path="/local/bar.jpg",excepted_name="cat.jpg")
            >>> self.download_as_file(remote_file_path="/foo/bar.jpg",local_file_path="/local/bar.jpg",excepted_name="cat.jpg")

        :param remote_file_path:                remote file path and just support single file
        :param local_file_path:                 local file path which download
        :param excepted_name: excepted name     just excepted name which want to rename
        :return:
        """
        if is_blank(remote_file_path):
            raise DropboxAPIException(
                message="#download_as_file, remote file is blank !")

        if remote_file_path.endswith(DROPBOX_FILE_SEP):
            raise DropboxAPIException(
                message="#download_as_file, remote file path format error !")

        # if `remote_file_path` not start with `/` , and combine `/` to head;
        # transform `foo/bar.jpg` to `/foo/bar.jpg`
        remote_file_path = remote_file_path if remote_file_path.startswith(
            DROPBOX_FILE_SEP) else DROPBOX_FILE_SEP + remote_file_path

        rfpp = FilePathParser(full_path_file_string=remote_file_path)
        lfpp = FilePathParser(full_path_file_string=local_file_path)

        # if source name not in remote file path , throw `DropboxAPIException`
        if is_not_blank(rfpp.source_name):
            raise DropboxAPIException(
                message=
                "#download_as_file , remote file path source name is blank !")

        if lfpp.is_blank:
            raise DropboxAPIException(
                message="#download_as_file , local file path is blank !")

        # fix if local folder is not exist , or create it
        if not os.path.exists(lfpp.source_path):
            os.mkdir(lfpp.source_path)

        # if source name not in local file path , throw `DropboxAPIException`
        # if is_blank(lfpp.source_name):
        #     raise DropboxAPIException(message="#download_as_file , local file path source name is blank !")

        # rename local file path . if excepted name exist , replace source name to excepted name.
        #  excepted_name = "cat.jpg" , local_path_file = "/foo/bar.jgp" => "foo/cat.jpg"
        if is_not_blank(excepted_name):
            efpp = FilePathParser(full_path_file_string=excepted_name)
            if is_not_blank(efpp.source_name):
                local_file_path = lfpp.set_source_name(
                    excepted_source_name=excepted_name)
        elif is_blank(lfpp.source_name):
            local_file_path = lfpp.set_source_name(
                excepted_source_name=rfpp.source_name)

        simple_file_metadata, bytes_array = self.async_download_from_dropbox(
            remote_file_path=remote_file_path)
        buffer = io.StringIO()
        buffer.write(bytes_array)

        # local file write
        with open_file(file_name=local_file_path, mode="wb") as lwf:
            lwf.write(buffer.getvalue())

        if not buffer.closed():
            buffer.close()
        return simple_file_metadata
Пример #5
0
    def upload_from_external_url(self,
                                 external_url: str,
                                 remote_file_path: str = None,
                                 remote_folder_path: str = None,
                                 excepted_name: str = None,
                                 **kwargs) -> SimpleFileMetadata:
        """
        upload file which from external url

        in case of all parameters is not none

        `excepted_name`       first priority
        `remote_file_path`    second priority
        `remote_folder`       third priority

        :param external_url:        url from external source
        :param remote_file_path     remote file path
        :param remote_folder_path   remote folder_path
        :param excepted_name        just only excepted name , not with dir path
        :param kwargs:              requests parameters
        :return:
        """
        if is_blank(remote_file_path):
            if is_blank(remote_folder_path):
                raise DropboxAPIException(
                    "#upload_from_external_url, remote_file_path is blank and remote_folder_path "
                    "is also blank !")

            if not remote_folder_path.startswith(DROPBOX_FILE_SEP):
                remote_folder_path = DROPBOX_FILE_SEP + remote_folder_path
            if not remote_folder_path.endswith(DROPBOX_FILE_SEP):
                remote_folder_path = remote_folder_path + DROPBOX_FILE_SEP
            remote_file_path = remote_folder_path

        if not remote_file_path.startswith(DROPBOX_FILE_SEP):
            remote_file_path = DROPBOX_FILE_SEP + remote_file_path

        euup = UrlPathParser(full_path_file_string=external_url)

        if euup.is_blank:
            raise DropboxAPIException(
                "#upload_from_external , upload external url is blank!")
        if euup.is_not_http:
            raise DropboxAPIException(
                "#upload_from_external , upload external url is unknown protocol!"
            )

        rfpp = FilePathParser(full_path_file_string=remote_file_path)

        if is_not_blank(excepted_name):
            if DROPBOX_FILE_SEP in excepted_name:
                excepted_name = DROPBOX_FILE_SEP + excepted_name \
                    if not excepted_name.startswith(DROPBOX_FILE_SEP) else excepted_name
                remote_file_path = excepted_name
            else:
                remote_file_path = rfpp.set_source_name(
                    excepted_name.split(DROPBOX_FILE_SEP)[-1])

        else:
            remote_file_source = rfpp.source_name
            # case one:
            # remote_file_path  /DEFAULT/A/
            # local_file_path   /foo/bar.jpg
            # auto set          /DEFAULT/A/bar.jpg
            if is_blank(remote_file_source):
                remote_file_path = os.path.join(remote_file_path,
                                                euup.source_name)
            # case two:
            # remote_file_path  /DEFAULT/A/bar
            # local_file_path   /foo/bar.jpg
            # auto set          /DEFAULT/A/bar.jpg
            elif not remote_file_source.__contains__(
                    DROPBOX_FILE_DOT) and is_not_blank(euup.source_suffix):
                remote_file_path = remote_file_path + DROPBOX_FILE_DOT + euup.source_suffix

            # case three:
            # remote_file_path  /DEFAULT/A/bar
            # local_file_path   /foo/bar
            # auto set          /DEFAULT/A/bar

        if is_debug():
            logger.debug(
                "#upload_from_external_url , remote_file_path=%s, external_url=%s"
                % (remote_file_path, external_url))

        async def _arequest_external_url():
            async def _inner_request():
                return requests.get(url=external_url, **kwargs, stream=True)

            _res = await _inner_request()
            return _res

        res = self.loop.run_until_complete(_arequest_external_url())
        # Tips: Anti spider policy , 可以把status code 设置非200来迷惑爬虫
        if res.status_code != 200:
            error_msg = "#upload_from_external_url , fail to request ,  url=%s , msg=%s", (
                external_url, res.txt)
            logger.error(error_msg)
            raise DropboxAPIException(message=error_msg)
        # request success
        content_type = res.headers.get("Content-Type")

        if is_debug():
            logger.info("#upload_from_external_url request <%s> success!" %
                        external_url)

        if DROPBOX_FILE_DOT not in remote_file_path.split(
                DROPBOX_FILE_SEP)[-1]:
            # get file type (suffix)
            file_suffix = get_suffix(mime=content_type)
            if file_suffix is not None:
                remote_file_path = remote_file_path + DROPBOX_FILE_DOT + file_suffix

        buffer = io.BytesIO()
        for chunk in res.iter_content(chunk_size=20 * 1024):
            if chunk:
                buffer.write(chunk)
            else:
                break

        if is_debug():
            logger.debug("#upload_from_external_url , remote_file_path=%s" %
                         remote_file_path)

        md = self.async_upload_bytes(file_bytes=buffer.getvalue(),
                                     remote_file_path=remote_file_path)
        if not buffer.closed:
            buffer.close()
        return md
Пример #6
0
    def upload_from_local(self,
                          local_file_path: str,
                          remote_file_path: str = None,
                          remote_folder_path: str = None,
                          excepted_name: str = None) -> SimpleFileMetadata:
        """
        upload to dropbox with excepted name

        `excepted_name`       first priority
        `remote_file_path`    second priority
        `remote_folder`       third priority

        :param local_file_path:             file path in local
        :param remote_file_path:            file path in dropbox
        :param remote_folder_path           folder in dropbox
        :param excepted_name:               excepted name which want to rename


        sample as
            >>> self.download_as_file(local_file_path='/foo/bar.jpg',remote_file_path='/DEFAULT/cat.jpg')
            # `/DEFAULT/cat.jpg`

            >>> self.download_as_file(local_file_path='/foo/bar.jpg',remote_file_path='DEFAULT/cat.jpg')
            # `/DEFAULT/cat.jpg`

            >>> self.download_as_file(local_file_path='/foo/bar.jpg',remote_file_path='DEFAULT/cat.jpg',
            >>> excepted_name='dog.jpg')
            # `/DEFAULT/dog.jpg`

            >>> self.download_as_file(local_file_path='/foo/bar.jpg',remote_file_path='DEFAULT/cat.jpg',
            >>> excepted_name='EXCEPTED_DIR/dog.jpg')
            # `/EXCEPTED_DIR/dog.jpg`

            >>> self.download_as_file(local_file_path='/foo/bar.jpg',remote_folder_path='REMOTE_FOLDER',
            >>> excepted_name='dog.jpg')
            # `/REMOTE_FOLDER/dog.jpg`


        :return:
        """

        global metadata
        if is_blank(remote_file_path):
            if is_blank(remote_folder_path):
                raise DropboxAPIException(
                    "#upload_from_local, remote_file_path is blank and remote_folder_path "
                    "is also blank !")

            if not remote_folder_path.startswith(DROPBOX_FILE_SEP):
                remote_folder_path = DROPBOX_FILE_SEP + remote_folder_path
            if not remote_folder_path.endswith(DROPBOX_FILE_SEP):
                remote_folder_path = remote_folder_path + DROPBOX_FILE_SEP
            remote_file_path = remote_folder_path

        if not remote_file_path.startswith(DROPBOX_FILE_SEP):
            remote_file_path = DROPBOX_FILE_SEP + remote_file_path

        lfpp = FilePathParser(full_path_file_string=local_file_path)

        if lfpp.is_blank:
            raise DropboxAPIException(
                "#upload_from_local, local file path is blank !")

        if lfpp.is_not_exist:
            raise DropboxAPIException(
                "#upload_from_local, local file path is not exist !")

        if lfpp.is_not_file:
            raise DropboxAPIException(
                "#upload_from_local, local file path is not a file !")

        rfpp = FilePathParser(full_path_file_string=remote_file_path)
        if is_not_blank(excepted_name):
            if DROPBOX_FILE_SEP in excepted_name:
                remote_file_path = DROPBOX_FILE_SEP + excepted_name if not excepted_name.startswith(
                    DROPBOX_FILE_SEP) else excepted_name
            else:
                remote_file_path = rfpp.set_source_name(
                    excepted_name.split(DROPBOX_FILE_SEP)[-1])

        else:
            remote_file_source = rfpp.source_name
            # case one:
            # remote_file_path  /DEFAULT/A/
            # local_file_path   /foo/bar.jpg
            # auto set          /DEFAULT/A/bar.jpg
            if is_blank(remote_file_source):
                remote_file_path = os.path.join(remote_file_path,
                                                lfpp.source_name)

            # case two:
            # remote_file_path  /DEFAULT/A/bar
            # local_file_path   /foo/bar.jpg
            # auto set          /DEFAULT/A/bar.jpg
            elif not remote_file_source.__contains__(
                    DROPBOX_FILE_DOT) and is_not_blank(lfpp.source_suffix):
                remote_file_path = remote_file_path + DROPBOX_FILE_DOT + lfpp.source_suffix

            # case three:
            # remote_file_path  /DEFAULT/A/bar
            # local_file_path   /foo/bar
            # auto set          /DEFAULT/A/bar

        file_size = os.path.getsize(local_file_path)
        chunk_size = 10 * 1024 * 1024
        if file_size <= chunk_size:
            if is_debug():
                logger.debug("> uploading tiny file")
            with open_file(file_name=local_file_path, mode="rb") as fr:
                metadata = self.async_upload_bytes(
                    file_bytes=fr.read(), remote_file_path=remote_file_path)
        else:
            if is_debug():
                logger.debug("> uploading large file")
                metadata = self.async_upload_with_large_file(
                    local_file_path=local_file_path,
                    remote_file_path=remote_file_path,
                    chunk_size=chunk_size)

        if logger.level == logging.DEBUG:
            logger.debug("upload_from_local metadata is %s" % metadata)
        return metadata