diff --git a/app/services/image_importer.rb b/app/services/image_importer.rb new file mode 100644 index 0000000000..c6d2982426 --- /dev/null +++ b/app/services/image_importer.rb @@ -0,0 +1,22 @@ +class ImageImporter + def import(url, product) + attach(download(url), product) + end + + private + + def download(url) + local_file = Tempfile.new + remote_file = open(url) + IO.copy_stream(remote_file, local_file) + local_file + end + + def attach(file, product) + Spree::Image.create( + attachment: file, + viewable_id: product.master.id, + viewable_type: Spree::Variant, + ) + end +end diff --git a/lib/tasks/import_product_images.rake b/lib/tasks/import_product_images.rake new file mode 100644 index 0000000000..16b46e376d --- /dev/null +++ b/lib/tasks/import_product_images.rake @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +namespace :ofn do + namespace :import do + desc "Importing images for products from CSV" + task :product_images, [:filename] => [:environment] do |_task, args| + COLUMNS = [:producer, :name, :image_url] + + puts "Warning: use only with trusted URLs. This script will download whatever it can, including local secrets, and expose the file as an image file." + + raise "Filename required" if args[:filename].blank? + + csv = CSV.read(args[:filename], headers: true, header_converters: :symbol) + raise "CSV columns reqired: #{COLUMNS.map(&:to_s)}" if (COLUMNS - csv.headers).present? + + csv.each.with_index do |entry, index| + puts "#{index} #{entry[:producer]}, #{entry[:name]}" + enterprise = Enterprise.find_by_name! entry[:producer] + + product = Spree::Product.where(supplier: enterprise, + name: entry[:name], + deleted_at: nil).first + if product.nil? + puts " product not found." + next + end + + if product.images.first.nil? + ImageImporter.new.import(entry[:image_url], product) + puts " image added." + else + # image = product.images.first + # image.update(attachment: entry[:image_url]) + puts " image exists, not updated." + end + end + end + end +end diff --git a/spec/services/image_importer_spec.rb b/spec/services/image_importer_spec.rb new file mode 100644 index 0000000000..88ba329786 --- /dev/null +++ b/spec/services/image_importer_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: false + +require 'spec_helper' + +describe ImageImporter do + let(:url) { Rails.root.join("spec/fixtures/files/logo.png").to_s } + let(:product) { create(:product) } + + describe "#import" do + it "downloads and attaches to the product" do + expect { + subject.import(url, product) + }.to change { + Spree::Image.count + }.by(1) + + expect(product.images.count).to eq 1 + expect(product.images.first.attachment.size).to eq 6274 + end + end +end