3

I'm using paperclip to send files to S3, and i want to know how much space each user is consuming.

For each user i have a folder user/:id/files/.

I can register in my database how much space costs each file when i save it, but i prefere to check it directly at S3, there is an easy way?

felipepastorelima
  • 947
  • 1
  • 10
  • 23

2 Answers2

3

I am not sure this counts as easy and mind you I am doing this from the docs but...

Paperclip uses the aws-sdk so if you use it directly like this:

size = 0

AWS::S3::Bucket.objects.each do |object| #object should be an S3Object
  if object.metadata(name) =~ /user//:id//files/
    size += object.content_length #in bytes
  end
end

You should wind up with the total bytes used by each user. The only thing I am unsure on is the format of the name metadata for the object/file. According to this post the name should have the /user/:id/files/ format but I am not sure how the other items (e.g. user) figure in to it.

You can probably improve on that when you dig in a bit but I think the general idea is there.

I got this from these links:

AWSRubySDK

Bucket

Bucket.objects

S3Object

S3Object.metadata

S3Object.metadata(name)

S3Object.content_length

Community
  • 1
  • 1
ScottJShea
  • 7,041
  • 11
  • 44
  • 67
2

Building on top of @ScottJShea's answer, you can use the with_prefix(prefix)-method:

size = 0
AWS::S3::Bucket.objects.with_prefix('/user//:id//files/').each do |s3_object|
  size += s3_object.content_length
end

or:

AWS::S3::Bucket.objects.with_prefix('/user//:id//files/').inject(0) { 
  |sum, s3_object| sum + s3_object.content_length 
}

Also:

If you are iterating through objects that might be deleted, you will see an exception, you can rescue it like this:

AWS::S3::Bucket.objects.with_prefix('/user//:id//files/').inject(0) { 
  |sum, s3_object| sum + (s3_object.content_length rescue 0)
}
Kasper Grubbe
  • 923
  • 2
  • 14
  • 19