Last active
December 27, 2015 00:19
-
-
Save dodinas/7237377 to your computer and use it in GitHub Desktop.
My Model
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 Choice < ActiveRecord::Base | |
# Environment-specific direct upload url verifier screens for malicious posted upload locations. | |
DIRECT_UPLOAD_URL_FORMAT = %r{\Ahttps:\/\/s3\.amazonaws\.com\/mybucket\/(?<path>uploads\/.+\/(?<filename>.+))\z}.freeze | |
has_many :template_assignments | |
has_many :templates, :through => :template_assignments | |
# This method associates the attribute ":picture" with a file attachment | |
has_attached_file :picture, styles: { | |
thumb: '300x200>', | |
square: '200x200>', | |
large: '500x500>' | |
} | |
validates :direct_upload_url, presence: true, format: { with: DIRECT_UPLOAD_URL_FORMAT } | |
before_create :set_upload_attributes | |
after_create :queue_processing | |
# Store an unescaped version of the escaped URL that Amazon returns from direct upload. | |
def direct_upload_url=(escaped_url) | |
write_attribute(:direct_upload_url, (CGI.unescape(escaped_url) rescue nil)) | |
end | |
# Determines if file requires post-processing (image resizing, etc) | |
def post_process_required? | |
%r{^(image|(x-)?application)/(bmp|gif|jpeg|jpg|pjpeg|png|x-png)$}.match(upload_content_type).present? | |
end | |
# Final upload processing step | |
def self.transfer_and_cleanup(id) | |
choice = Choice.find(id) | |
direct_upload_url_data = DIRECT_UPLOAD_URL_FORMAT.match(choice.direct_upload_url) | |
s3 = AWS::S3.new | |
if choice.post_process_required? | |
choice.upload = URI.parse(URI.escape(chioce.direct_upload_url)) | |
else | |
paperclip_file_path = "documents/uploads/#{id}/original/#{direct_upload_url_data[:filename]}" | |
s3.buckets[Rails.configuration.aws[:bucket]].objects[paperclip_file_path].copy_from(direct_upload_url_data[:path]) | |
end | |
choice.processed = true | |
choice.save | |
s3.buckets[Rails.configuration.aws[:bucket]].objects[direct_upload_url_data[:path]].delete | |
end | |
protected | |
# Set attachment attributes from the direct upload | |
# @note Retry logic handles S3 "eventual consistency" lag. | |
def set_upload_attributes | |
tries ||= 5 | |
direct_upload_url_data = DIRECT_UPLOAD_URL_FORMAT.match(direct_upload_url) | |
s3 = AWS::S3.new | |
direct_upload_head = s3.buckets[Rails.configuration.aws[:bucket]].objects[direct_upload_url_data[:path]].head | |
self.upload_file_name = direct_upload_url_data[:filename] | |
self.upload_file_size = direct_upload_head.content_length | |
self.upload_content_type = direct_upload_head.content_type | |
self.upload_updated_at = direct_upload_head.last_modified | |
rescue AWS::S3::Errors::NoSuchKey => e | |
tries -= 1 | |
if tries > 0 | |
sleep(3) | |
retry | |
else | |
false | |
end | |
end | |
# Queue file processing | |
def queue_processing | |
Choice.delay.transfer_and_cleanup(id) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment