Repository: django-wiki/django-wiki

Issue:
"This backend doesn't support absolute urls" deleting image
I will try to explain the best as I can what I think is a bug but, given my relative knowledge of django could be some misconfiguration. Also, it could be more of a conflict between django wiki and S3 as storage.

The use case is: having a production cookiecutter django, with S3 configured, and django wiki as application. In fact locally this doesn't happen so I had to bring every AWS configuration locally to make it work.

When you delete an image, you get prompted if you want to delete the image. After that the method fires to delete the image. The problem is that ImageField using S3 storage class needs to use the "name" field instead of path because path isn't implemented in the storage class.

```
def on_image_revision_delete(instance, *args, **kwargs):
    if not instance.image:
        return
    # Remove image file
    path = instance.image.path.split("/")[:-1] #path returns not implemented, while .name works.
    instance.image.delete(save=False)
```

`diango.core.files.storage.py`

```
def path(self, name):
        """
        Return a local filesystem path where the file can be retrieved using
        Python's built-in open() function. Storage systems that can't be
        accessed using open() should *not* implement this method.
        """
        raise NotImplementedError("This backend doesn't support absolute paths.")
```
I realize that my explanation is faulty and missing some basic knowledge, sorry for that, I'm currently deepening my django skills so maybe there is something basic that I might be missing. I hope this helps figuring out a way to allow using S3 as a storage.

It would be much appreciated to know if this is an issue or if I just missed something. I will post to stack overflow for help anyway but if this is an error I'd like to help fixing it.


Discussion:
Hi @superandrew 

Thanks for the issue report! I'm quite convinced that it's a real issue from your thorough description :)

You are very welcome to contribute a PR that adds conditions to the signal, such that it takes a storage backend into account which doesn't support a full path.
I will try, sorry for being so noob in python but how is the best way to override the module so that I can test my code? Should I fork the repository and import with pip using github link or am I completely off? :)
I assume you are using some kind of virtualenv in your project. Activate that.

Then, in a different folder, clone the repo and run `pip install -e .`. This will install it in "editable mode", which is for developers. Your project will use the application directly as a link to the cloned repo and all changes you make are instant.

See: http://django-wiki.readthedocs.io/en/master/development/index.html
thanks @benjaoming. Perfectly clear and cool. However I'm having a hard time modifying code because I'm currently remote debugging a docker compose setup, in pycharm. When it gets down to the source code of models.py, changes are not persistent nor debuggable. I tried deleting pycharm's cache, moving to another virtualenv.. to no avail.

Anyway don't worry, I'll figure it out, I hope. I'm just writing this in case you have any advice for this setup.
Good luck with that :) Not to come across as arrogant, but it sounds like there's a bit of learning and healthy development environment tweaking in it for you :)

I have a feeling that the fix can be clean and simple, but I'm not using S3, so I can't really get a proper dev env bootstrapped to fix it.
Don't worry, I might be a noob in django and python, but I consider myself a stubborn debugging ninja, so I'll figure it out in one way or another. I' more worried by the hope to provide a "djangoesque" fix :)
@benjaoming I had to import all wiki inside the project, but it's temporary, so now I can debug. Could you please point me on the best and simple way to check if the storage supports the path or name method?

I think the solutions has to be implemented on the on_image_revision_delete signal, right?

i have instance.image.storage as a property to inspect, should I find the backend class there on in other variables from the context?
this is something that works in my case, should work in other cases, I'm not sure it's the best way to do it:
models.py

   
    def on_image_revision_delete(instance, *args, **kwargs):
        if not instance.image:
            return
    # Remove image file

    #start changes
    import storages
    if isinstance(instance.image.storage, (storages.backends.s3boto3.S3Boto3Storage,)):
        path = instance.image.name.split("/")[:-1]
    else:
        path = instance.image.path.split("/")[:-1]
    #end changes


Could you check if it makes sense? In case it does would you mind putting it on a 0.4.5a release? I'd be happy to test it. If you want I could make a PR in case, I'm not sure which other backends have the same unimplemented path method though.

Resolving patch:
diff --git a/src/wiki/plugins/images/models.py b/src/wiki/plugins/images/models.py
--- a/src/wiki/plugins/images/models.py
+++ b/src/wiki/plugins/images/models.py
@@ -107,8 +107,15 @@ def __str__(self):
 def on_image_revision_delete(instance, *args, **kwargs):
     if not instance.image:
         return
+
     # Remove image file
     instance.image.delete(save=False)
+    
+    try:
+        path = instance.image.path.split("/")[:-1]
+    except NotImplementedError:
+            # This backend storage doesn't implement 'path' so there is no path to delete
+        return
 
     try:
         path = instance.image.path.split("/")[:-1]


Test patch: