Save a picture in S3 from a temporary URL

1.6k views Asked by At

I am developing a website on ruby on rails where users can upload pictures thanks to paperclip, it is stored in amazon S3. After, they can modify pictures thanks to aviary. But when i want to save the new pictures, aviary just gave me an temporary URL where i can get my modified picture.

Does paperclip can do it ? I don't think it can save an picture from an URL and store it to S3 ?

I've searched for a week now, and i don't know the best way to do it. I've read about filepicker, but the account to store data in S3 files isn't free ...

Finally i've heard about this s3 https://github.com/qoobaa/s3, but i don't understand how to use it. I have installed gem s3, but when i set require 's3' , it is not recognize.

What is the best to do?

2

There are 2 answers

0
Miki On

Why don't you pass the URL that Aviary generates to your server and upload the new photo from there? The code below does that in Python/Django:

@login_required    
@csrf_exempt
def upload_from_url(request):
    origin_url = request.POST.get("origin_url")
    name = request.POST.get("name")

    try:
        conn = boto.connect_s3(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
        bucket_name = settings.AWS_UGC_STORAGE_BUCKET_NAME
        bucket = conn.get_bucket(bucket_name)
        k = Key(bucket)

        k.key = name   
        file_object = urllib2.urlopen(origin_url)
        fp = StringIO.StringIO(file_object.read())
        k.set_contents_from_file(fp)

        return HttpResponse("Success")
    except Exception, e:
        return HttpResponse(e, mimetype='application/javascript')

Hope this helps.

0
Jan Klimo On

Paperclip has matured a lot since this question was answered. If you want to save files by passing a URL, as of Paperclip v3.1.4, you can just assign the URL to your Paperclip attachment attribute.

Let's say I have a class User and my attachment is called avatar. We'll have the following in our User model:

has_attached_file :avatar

# Validate the attached image is image/jpg, image/png, etc
# This is required by later releases of Paperclip
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/

In our view, we can define a hidden field that will accept the temporary URL received from Aviary:

= f.hidden_field :avatar, id: 'avatar'

We can set the value of this hidden field with the Aviary onSave callback:

var featherEditor = new Aviary.Feather({
  apiKey: '#{ENV['AVIARY_KEY']}',
  onSave: function(imageID, newURL) {
    var img = document.getElementById(imageID);
    img.src = newURL;

    var avatar = document.getElementById('avatar');
    avatar.value = newURL;
    featherEditor.close();
  }
});

Within onSave, you can use AJAX to update the User object, use jQuery's .submit() to submit the form, or let the user submit it when they want.