Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle project images when remixing #49

Merged
merged 5 commits into from
Apr 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/concepts/project/operation/create_remix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ def create_remix(original_project, params, user_id)
proj.remixed_from_id = original_project.id
end

original_project.images.each do |image|
remix.images.attach(image.blob)
end

params[:components].each do |x|
remix.components.build(x.slice(:name, :extension, :content, :index))
end
Expand Down
39 changes: 36 additions & 3 deletions lib/tasks/projects.rake
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ namespace :projects do
end

project_images = proj_config['IMAGES'] || []
delete_removed_images(project, project_images)
project_images.each do |image_name|
project.images.attach(io: File.open(File.dirname(__FILE__) + "/project_components/#{dir}/#{image_name}"),
filename: image_name)
attach_image_if_needed(project, image_name, dir)
end

project.save
Expand All @@ -38,8 +38,41 @@ def find_project(proj_config)
project = Project.find_by(identifier: proj_config['IDENTIFIER'])
project.name = proj_config['NAME']
project.components.each(&:destroy)
project.images.purge
end

project
end

def delete_removed_images(project, images_to_attach)
existing_images = project.images.map { |x| x.blob.filename.to_s }
diff = existing_images - images_to_attach
return if diff.empty?

diff.each do |filename|
img = project.images.find { |i| i.blob.filename == filename }
img.purge
end
end

def attach_image_if_needed(project, image_name, dir)
existing_image = project.images.find { |i| i.blob.filename == image_name }

if existing_image
return if existing_image.blob.checksum == image_checksum(image_name, dir)

existing_image.purge
end
project.images.attach(io: File.open(File.dirname(__FILE__) + "/project_components/#{dir}/#{image_name}"),
filename: image_name)
end

def image_checksum(image_name, dir)
io = File.open(File.dirname(__FILE__) + "/project_components/#{dir}/#{image_name}")
OpenSSL::Digest.new('MD5').tap do |checksum|
while (chunk = io.read(5.megabytes))
checksum << chunk
end

io.rewind
end.base64digest
end
15 changes: 14 additions & 1 deletion spec/concepts/project/operation/create_remix_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
subject(:create_remix) { described_class.call(params: remix_params, user_id: user_id, original_project: original_project) }

let(:user_id) { 'e0675b6c-dc48-4cd6-8c04-0f7ac05af51a' }
let!(:original_project) { create(:project, :with_components) }
let!(:original_project) { create(:project, :with_components, :with_attached_image) }
let(:remix_params) do
component = original_project.components.first
{
Expand Down Expand Up @@ -59,6 +59,19 @@
expect(remixed_attrs).to eq(original_attrs)
end

it 'links remix to attached images' do
remixed_project = create_remix[:project]
expect(remixed_project.images.length).to eq(original_project.images.length)
end

it 'creates a new attachment' do
expect { create_remix }.to change(ActiveStorage::Attachment, :count).by(1)
end

it 'does not create a new image' do
expect { create_remix }.not_to change(ActiveStorage::Blob, :count)
end

it 'creates new components' do
expect { create_remix }.to change(Component, :count).by(1)
end
Expand Down
8 changes: 5 additions & 3 deletions spec/factories/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
end
end

trait :with_attached_images do
after(:create) do |object|
object.images.attach(fixture_file_upload(Rails.root.join('spec/fixtures/test_image_1.png'), 'image/png'))
trait :with_attached_image do
after(:build) do |object|
object.images.attach(io: File.open(Rails.root.join('spec/fixtures/files/test_image_1.png')),
filename: 'test_image',
content_type: 'image/png')
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions spec/models/project_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
it { is_expected.to have_many(:children) }
it { is_expected.to belong_to(:parent).optional(true) }
it { is_expected.to have_many_attached(:images) }

it 'purges attached images' do
expect(described_class.reflect_on_attachment(:images).options[:dependent]).to eq(:purge_later)
end
end

describe 'identifier not nil' do
Expand Down