Skip to content

Commit 6989851

Browse files
committed
Merge pull request discourse#1038 from ZogStriP/keep-uploads-reverse-index-up-to-date
Keep uploads reverse index up to date
2 parents 14e7bb4 + 7bdc616 commit 6989851

10 files changed

Lines changed: 62 additions & 16 deletions

File tree

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ config/fog_credentials.yml
6464

6565
/public/uploads
6666
/public/stylesheet-cache/*
67-
/public/downloads
68-
/public/images
6967

7068
# Scripts used for downloading/refreshing db
7169
script/download_db

app/models/upload.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ def create_thumbnail!
3838

3939
def self.create_for(user_id, file)
4040
# compute the sha
41-
sha = Digest::SHA1.file(file.tempfile).hexdigest
41+
sha1 = Digest::SHA1.file(file.tempfile).hexdigest
4242
# check if the file has already been uploaded
43-
upload = Upload.where(sha: sha).first
43+
upload = Upload.where(sha1: sha1).first
4444

4545
# otherwise, create it
4646
if upload.blank?
@@ -53,25 +53,25 @@ def self.create_for(user_id, file)
5353
user_id: user_id,
5454
original_filename: file.original_filename,
5555
filesize: File.size(file.tempfile),
56-
sha: sha,
56+
sha1: sha1,
5757
width: width,
5858
height: height,
5959
url: ""
6060
})
6161
# make sure we're at the beginning of the file (FastImage is moving the pointer)
6262
file.rewind
6363
# store the file and update its url
64-
upload.url = Upload.store_file(file, sha, image_info, upload.id)
64+
upload.url = Upload.store_file(file, sha1, image_info, upload.id)
6565
# save the url
6666
upload.save
6767
end
6868
# return the uploaded file
6969
upload
7070
end
7171

72-
def self.store_file(file, sha, image_info, upload_id)
73-
return S3.store_file(file, sha, image_info, upload_id) if SiteSetting.enable_s3_uploads?
74-
return LocalStore.store_file(file, sha, image_info, upload_id)
72+
def self.store_file(file, sha1, image_info, upload_id)
73+
return S3.store_file(file, sha1, image_info, upload_id) if SiteSetting.enable_s3_uploads?
74+
return LocalStore.store_file(file, sha1, image_info, upload_id)
7575
end
7676

7777
def self.uploaded_regex
@@ -105,11 +105,11 @@ def self.asset_host
105105
# url :string(255) not null
106106
# created_at :datetime not null
107107
# updated_at :datetime not null
108-
# sha :string(255)
108+
# sha1 :string(40)
109109
#
110110
# Indexes
111111
#
112-
# index_uploads_on_sha (sha) UNIQUE
112+
# index_uploads_on_sha1 (sha1) UNIQUE
113113
# index_uploads_on_user_id (user_id)
114114
#
115115

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class RenameShaColumn < ActiveRecord::Migration
2+
def up
3+
remove_index :uploads, :sha
4+
rename_column :uploads, :sha, :sha1
5+
change_column :uploads, :sha1, :string, limit: 40
6+
add_index :uploads, :sha1, unique: true
7+
end
8+
9+
def down
10+
remove_index :uploads, :sha1
11+
change_column :uploads, :sha1, :string, limit: 255
12+
rename_column :uploads, :sha1, :sha
13+
add_index :uploads, :sha, unique: true
14+
end
15+
end

lib/cooked_post_processor.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ def post_process_images
3636
# retrieve the associated upload, if any
3737
upload = get_upload_from_url(img['src'])
3838
if upload.present?
39+
# update reverse index
40+
associate_to_post upload
3941
# create a thumbnail
4042
upload.create_thumbnail!
4143
# optimize image
@@ -87,6 +89,13 @@ def get_upload_from_url(url)
8789
end
8890
end
8991

92+
def associate_to_post(upload)
93+
return if PostUpload.where(post_id: @post.id, upload_id: upload.id).count > 0
94+
PostUpload.create({ post_id: @post.id, upload_id: upload.id })
95+
rescue ActiveRecord::RecordNotUnique
96+
# do not care if it's already associated
97+
end
98+
9099
def optimize_image(img)
91100
return img["src"]
92101
# 1) optimize using image_optim

lib/local_store.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module LocalStore
22

3-
def self.store_file(file, sha, image_info, upload_id)
3+
def self.store_file(file, sha1, image_info, upload_id)
44
clean_name = Digest::SHA1.hexdigest("#{Time.now.to_s}#{file.original_filename}")[0,16] + ".#{image_info.type}"
55
url_root = "/uploads/#{RailsMultisite::ConnectionManagement.current_db}/#{upload_id}"
66
path = "#{Rails.root}/public#{url_root}"

lib/s3.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
module S3
22

3-
def self.store_file(file, sha, image_info, upload_id)
3+
def self.store_file(file, sha1, image_info, upload_id)
44
raise Discourse::SiteSettingMissing.new("s3_upload_bucket") if SiteSetting.s3_upload_bucket.blank?
55
raise Discourse::SiteSettingMissing.new("s3_access_key_id") if SiteSetting.s3_access_key_id.blank?
66
raise Discourse::SiteSettingMissing.new("s3_secret_access_key") if SiteSetting.s3_secret_access_key.blank?
77

88
@fog_loaded = require 'fog' unless @fog_loaded
99

10-
remote_filename = "#{upload_id}#{sha}.#{image_info.type}"
10+
remote_filename = "#{upload_id}#{sha1}.#{image_info.type}"
1111

1212
options = S3.generate_options
1313
directory = S3.get_or_create_directory(SiteSetting.s3_upload_bucket, options)

spec/components/cooked_post_processor_spec.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,23 @@ def cpp(cooked = nil, options = {})
5757

5858
end
5959

60+
context 'with uploaded images in the post' do
61+
before do
62+
@topic = Fabricate(:topic)
63+
@post = Fabricate(:post_with_uploads, topic: @topic, user: @topic.user)
64+
@cpp = CookedPostProcessor.new(@post)
65+
@cpp.expects(:get_upload_from_url).returns(Fabricate(:upload))
66+
@cpp.expects(:get_size).returns([100,200])
67+
end
68+
69+
it "keeps reverse index up to date" do
70+
@cpp.post_process_images
71+
@post.uploads.reload
72+
@post.uploads.count.should == 1
73+
end
74+
75+
end
76+
6077
context 'with unsized images in the post' do
6178
let(:user) { Fabricate(:user) }
6279
let(:topic) { Fabricate(:topic, user: user) }

spec/fabricators/post_fabricator.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@
4040
"
4141
end
4242

43+
Fabricator(:post_with_uploads, from: :post) do
44+
cooked "
45+
<img src='/uploads/default/1/1234567890123456.jpg' height='100' width='100'>
46+
"
47+
end
48+
49+
4350
Fabricator(:basic_reply, from: :post) do
4451
user(:coding_horror)
4552
reply_to_post_number 1

spec/fabricators/upload_fabricator.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
filesize 1234
55
width 100
66
height 200
7-
url "/uploads/default/123456789.jpg"
7+
url "/uploads/default/1/1234567890123456.jpg"
88
end

spec/models/upload_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
upload.user_id.should == user_id
3535
upload.original_filename.should == logo.original_filename
3636
upload.filesize.should == File.size(logo.tempfile)
37-
upload.sha.should == Digest::SHA1.file(logo.tempfile).hexdigest
37+
upload.sha1.should == Digest::SHA1.file(logo.tempfile).hexdigest
3838
upload.width.should == 244
3939
upload.height.should == 66
4040
upload.url.should == url

0 commit comments

Comments
 (0)