Last active
May 26, 2016 17:38
-
-
Save brianlittmann/241c73c5c13488e39b6befb450f5dc16 to your computer and use it in GitHub Desktop.
Save image versions with Refile with streaming as a fallback
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class AwsUploader | |
CLIENT = Aws::S3::Client.new | |
BUCKET = Rails.configuration.x.aws["output_bucket"] | |
def self.upload(file, key) | |
CLIENT.put_object({ | |
bucket: BUCKET, | |
key: key, | |
body: file, | |
content_length: file.size | |
}) | |
end | |
def self.delete(key) | |
resp = CLIENT.list_objects({ | |
bucket: BUCKET, | |
prefix: key | |
}) | |
CLIENT.delete_objects({ | |
bucket: BUCKET, | |
delete: { | |
objects: resp.contents.map{|c| c.to_hash.slice(:key)} | |
} | |
}) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class CacheThumbnailsJob < ActiveJob::Base | |
queue_as :default | |
def perform(post) | |
versions = {} | |
extension = post.thumbnail_attacher.extension | |
source_file = Refile.store.get(post.thumbnail_id).download | |
Post.thumbnails.each do |k, attrs| | |
filename = "#{k}.#{extension}" | |
key = [post.thumbnail_prefix, filename].join("/") | |
file = Refile.processors[attrs[:processor]].call(source_file, attrs[:width], attrs[:height]) | |
AwsUploader.upload(file, key) | |
versions[k] = filename | |
end | |
# thumbnail_versions is an hstore column | |
post.update(thumbnail_versions: versions) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DeleteThumbnailsJob < ActiveJob::Base | |
queue_as :default | |
def perform(key) | |
AwsUploader.delete(key) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Post < ActiveRecord::Base | |
attachment :thumbnail, type: :image | |
def self.thumbnails | |
@thumbnails ||= { | |
md: { | |
processor: "fill", | |
width: 480, | |
height: 270 | |
}, | |
md2x: { | |
processor: "fill", | |
width: 960, | |
height: 540 | |
} | |
} | |
end | |
after_save :cache_thumbnails | |
def thumbnail_prefix(key=nil) | |
['thumbnails', (key || thumbnail_id)].join('/') | |
end | |
private | |
def cache_thumbnails | |
if thumbnail_id_changed? | |
CacheThumbnailsJob.perform_later(self) if thumbnail_id.present? | |
DeleteThumbnailsJob.perform_later(thumbnail_prefix(thumbnail_id_was)) if thumbnail_id_was.present? | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module PostsHelper | |
def thumbnail_url(post, version) | |
filename = post.thumbnail_versions[version.to_s] | |
if filename.present? | |
[Rails.configuration.x.cdn_host, post.thumbnail_prefix, filename].join('/') | |
else | |
# Fallback to Refile URL if not generated yet | |
specs = Post.thumbnails[version] | |
attachment_url(post, :thumbnail, specs[:processor], specs[:width], specs[:height]) | |
end | |
end | |
end |
You could have a cron job that runs a Rake task which uses the AWS SDK to check if an object exists, and if not generate some thumbnails. In regards to deleting old thumbnails, you'd either need to keep track of the old image hashes/filenames or run some sort of diff on what's in your local database vs. what's listed in S3 and delete anything in S3 that isn't stored locally (which sounds kinda clunky).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This looks nice. I will try to adopt it.
But I don't want the jobs to run. I'd rather delete all thumbnails after let's say 30 days and the call to a thumbnail checks if it exists and if not generates it. I don't know if this is possible. What do you think?