make sure we only do the work once

This commit is contained in:
Régis Hanol 2013-06-15 11:52:40 +02:00
parent f94e4ffdcb
commit 8a98310cf9
6 changed files with 22 additions and 24 deletions

View File

@ -13,17 +13,18 @@ class Upload < ActiveRecord::Base
validates_presence_of :original_filename
def self.create_for(user_id, file)
# retrieve image info
image_info = FastImage.new(file.tempfile, raise_on_failure: true)
# compute image aspect ratio
width, height = ImageSizer.resize(*image_info.size)
# compute the sha
sha = Digest::SHA1.file(file.tempfile).hexdigest
# check if the file has already been uploaded
upload = Upload.where(sha: sha).first
# otherwise, create it
if upload.blank?
# retrieve image info
image_info = FastImage.new(file.tempfile, raise_on_failure: true)
# compute image aspect ratio
width, height = ImageSizer.resize(*image_info.size)
# create a db record (so we can use the id)
upload = Upload.create!({
user_id: user_id,
original_filename: file.original_filename,
@ -33,23 +34,20 @@ class Upload < ActiveRecord::Base
height: height,
url: ""
})
# make sure we're at the beginning of the file (FastImage is moving the pointer)
file.rewind
# store the file and update its url
upload.url = Upload.store_file(file, image_info, upload.id)
upload.url = Upload.store_file(file, sha, image_info, upload.id)
# save the url
upload.save
end
# return the uploaded file
upload
end
def self.store_file(file, image_info, upload_id)
return S3.store_file(file, image_info, upload_id) if SiteSetting.enable_s3_uploads?
return LocalStore.store_file(file, image_info, upload_id)
def self.store_file(file, sha, image_info, upload_id)
return S3.store_file(file, sha, image_info, upload_id) if SiteSetting.enable_s3_uploads?
return LocalStore.store_file(file, sha, image_info, upload_id)
end
end

View File

@ -1,6 +1,6 @@
module LocalStore
def self.store_file(file, image_info, upload_id)
def self.store_file(file, sha, image_info, upload_id)
clean_name = Digest::SHA1.hexdigest("#{Time.now.to_s}#{file.original_filename}")[0,16] + ".#{image_info.type}"
url_root = "/uploads/#{RailsMultisite::ConnectionManagement.current_db}/#{upload_id}"
path = "#{Rails.root}/public#{url_root}"
@ -15,4 +15,4 @@ module LocalStore
return Discourse::base_uri + "#{url_root}/#{clean_name}"
end
end
end

View File

@ -1,15 +1,13 @@
module S3
def self.store_file(file, image_info, upload_id)
def self.store_file(file, sha, image_info, upload_id)
raise Discourse::SiteSettingMissing.new("s3_upload_bucket") if SiteSetting.s3_upload_bucket.blank?
raise Discourse::SiteSettingMissing.new("s3_access_key_id") if SiteSetting.s3_access_key_id.blank?
raise Discourse::SiteSettingMissing.new("s3_secret_access_key") if SiteSetting.s3_secret_access_key.blank?
@fog_loaded = require 'fog' unless @fog_loaded
blob = file.read
sha1 = Digest::SHA1.hexdigest(blob)
remote_filename = "#{upload_id}#{sha1}.#{image_info.type}"
remote_filename = "#{upload_id}#{sha}.#{image_info.type}"
options = S3.generate_options
directory = S3.get_or_create_directory(SiteSetting.s3_upload_bucket, options)

View File

@ -21,8 +21,8 @@ describe LocalStore do
File.stubs(:open)
# The Time needs to be frozen as it is used to generate a clean & unique name
Time.stubs(:now).returns(Time.utc(2013, 2, 17, 12, 0, 0, 0))
#
LocalStore.store_file(file, image_info, 1).should == '/uploads/default/1/253dc8edf9d4ada1.png'
#
LocalStore.store_file(file, "", image_info, 1).should == '/uploads/default/1/253dc8edf9d4ada1.png'
end
end

View File

@ -16,7 +16,7 @@ describe S3 do
let(:image_info) { FastImage.new(file) }
before(:each) do
before(:each) do
SiteSetting.stubs(:s3_upload_bucket).returns("s3_upload_bucket")
SiteSetting.stubs(:s3_access_key_id).returns("s3_access_key_id")
SiteSetting.stubs(:s3_secret_access_key).returns("s3_secret_access_key")
@ -24,7 +24,7 @@ describe S3 do
end
it 'returns the url of the S3 upload if successful' do
S3.store_file(file, image_info, 1).should == '//s3_upload_bucket.s3.amazonaws.com/1e8b1353813a7d091231f9a27f03566f123463fc1.png'
S3.store_file(file, "SHA", image_info, 1).should == '//s3_upload_bucket.s3.amazonaws.com/1SHA.png'
end
after(:each) do

View File

@ -1,4 +1,5 @@
require 'spec_helper'
require 'digest/sha1'
describe Upload do
@ -31,6 +32,7 @@ describe Upload do
upload.user_id.should == user_id
upload.original_filename.should == logo.original_filename
upload.filesize.should == File.size(logo.tempfile)
upload.sha.should == Digest::SHA1.file(logo.tempfile).hexdigest
upload.width.should == 244
upload.height.should == 66
upload.url.should == url