GithubHelp home page GithubHelp logo

Comments (5)

merwok avatar merwok commented on June 24, 2024 1

This is a bit rough but functional:

https://gist.github.com/merwok/3365ed649500baf0aae3a5f3263fa7b5

The issues are:

  1. needs custom code to support «directories» on S3, e.g. by saving empty .keep files
  2. for my project, a tree of directories doesn’t really help, and most uploaded files are unique images (so I just need easy upload for my rich text fields)
  3. with django 2.1 and https://github.com/fabiocaccamo/django-admin-interface , the filebrowser templates and styles do not fit at all

I will probably remove/rewrite the whole filebrowser, but feel free to start from my code and improve it!

from django-filebrowser-no-grappelli.

smacker avatar smacker commented on June 24, 2024

Hi @merwok ! Thanks for the bug report!

Sadly, I don't use S3 storage but I believe you can make it work by using an older version of S3Boto3Storage which is compatible with this mixin.

Anyway I would recommend you create an issue or pull request to upstream: https://github.com/sehmaschine/django-filebrowser

from django-filebrowser-no-grappelli.

merwok avatar merwok commented on June 24, 2024

I wrote my own mixin and will put it in a gist!

from django-filebrowser-no-grappelli.

smacker avatar smacker commented on June 24, 2024

Hi @merwok !

Please feel free to open PR with you mixin.

I also see @FutureMind made this fix: FutureMind@0b9cda4

Does it work for you? I'll be happy to fix the issue if I somebody provide PR with a tested mixin.

from django-filebrowser-no-grappelli.

kudlatyamroth avatar kudlatyamroth commented on June 24, 2024

i used django-s3-storage
and with this code:

class S3Boto3Storage(S3Storage, StorageMixin):
    def path(self, name):
        return self._get_key_name(name)

    @_wrap_errors
    def meta(self, name):
        object_params = self._object_params(name)
        try:
            return self.s3_connection.head_object(**object_params)
        except (S3Error, ClientError):
            object_params['Key'] = object_params['Key'] + '/'
            return self.s3_connection.head_object(**object_params)

    def isfile(self, name):
        return self.exists(name)

    def isdir(self, name):
        dir_list = self.listdir(name)
        return any(dir_list)

    def move(self, old_file_name, new_file_name, allow_overwrite=False):
        if self.exists(new_file_name):
            if allow_overwrite:
                self.rmtree(new_file_name)
            else:
                raise S3Error(f"The destination file '{new_file_name}' exists and allow_overwrite is False")

        if self.isdir(old_file_name):
            self.makedirs(new_file_name)
            self._move_dir(old_file_name, new_file_name)
        else:
            self._move_file(old_file_name, new_file_name)

    def _move_dir(self, source, destination):
        dirs, files = self.listdir(source)
        for directory in dirs:
            source_dir = f"{source.rstrip('/')}/{directory}/"
            destination_dir = f"{destination.rstrip('/')}/{directory}/"
            self.move(source_dir, destination_dir)

        for file in files:
            if file == '.':
                continue
            source_path = '/'.join([source, file])
            destination_path = '/'.join([destination.rstrip('/'), file])
            self._move_file(source_path, destination_path)
        self.rmtree(source)

    def _move_file(self, source, destination):
        source_params = self._object_params(source)
        new_key_name = self._get_key_name(destination)
        extra_args = {
            'ACL': 'public-read'
        }

        try:
            self.s3_connection.copy(source_params, source_params['Bucket'], new_key_name, extra_args)
        except ClientError:
            raise S3Error(f"Couldn't copy '{source}' to '{destination}'")
        self.delete(source)

    def makedirs(self, name):
        put_params = self._object_put_params(name)
        if not put_params['Key'].endswith('/'):
            put_params['Key'] = f"{put_params['Key']}/"
        self.s3_connection.put_object(**put_params)

    def rmtree(self, name):
        dirs, files = self.listdir(name)
        for item in dirs:
            dir_path = '/'.join([name, item])
            self.rmtree(dir_path)
        for item in files:
            if item == '.':
                continue
            self.delete('/'.join([name, item]))
        self.delete(name)

    @_wrap_errors
    def delete(self, name):
        object_params = self._object_params(name)
        try:
            head = self.s3_connection.head_object(**object_params)
            self.s3_connection.delete_object(**object_params)
        except (S3Error, ClientError):
            object_params['Key'] = object_params['Key'] + '/'
            self.s3_connection.delete_object(**object_params)

    def setpermission(self, name):
        pass

it works for me.
but when we change dir name, it can take long time, so remember about setting long timeout in server...


updated rmtree function

from django-filebrowser-no-grappelli.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.