require 'uri' require 'faraday' require 'yaml' require 'date' require 'mini_magick' class Localizer IMAGE_FIELDS = ["media_artist_url"] RESIZED_SUFIX = "_resized.png" IMAGES_FOLDER = File.dirname(File.dirname(__FILE__))+'/images/' attr_reader :post_directory, :image_directory def initialize(post_directory, image_directory) @post_directory = post_directory @image_directory = image_directory end def localize_images Dir.foreach(@post_directory) do |file| next if !(file.end_with?('md') || file.end_with?('.markdown')) transform_file("#{@post_directory}#{File::SEPARATOR}#{file}") end end private def local_image_filename(url) uri = URI(url) "#{image_directory}#{File::SEPARATOR}#{File.basename(uri.path)}" end # downloads the file locally if it hasn't already been downloaded def ensure_local_image(url, local_file) return local_file if File.exist?(local_file) connection = Faraday.new do |faraday| faraday.adapter(Faraday.default_adapter) end response = download_file_helper(connection, url) File.open(local_file, 'wb') { |file| file << response.body } local_file end # helper to make sure that we can follow redirects, which can be important for # many of the cloud file sharing services out there. def download_file_helper(connection, url, redirect_limit = 5) raise "Too many redirects while downloading #{url}" if redirect_limit <= 0 response = connection.get(url) case response.status when 301, 302, 303, 307, 308 location = response.headers['location'] raise "Redirect received without Location header for #{url}" unless location download_file_helper(connection, location, redirect_limit - 1) when 200 response else raise "Error downloading file: #{response.status}" end end def transform_file(file) puts "Transforming #{file}" contents = File.read(file, encoding: 'UTF-8') # Step 1: get all the images that must be downloaded yaml = YAML.safe_load(contents, permitted_classes: [Date], aliases: true) yaml['talks'].each do |talk| IMAGE_FIELDS.each do |image_field| image_url = talk[image_field] if !image_url.nil? # Download image if it is on the internet if image_url.start_with?('http') || image_url.start_with?('https') local_image = local_image_filename(image_url) begin ensure_local_image(image_url, local_image) rescue puts "Error downloading locally for image: #{image_url}" next end else puts "Skipping downloading of image: #{image_url}" end # Create resized version if it does not existZ if !(image_url.end_with? RESIZED_SUFIX) local_image = image_url + RESIZED_SUFIX resized_url = File.basename(image_url) + RESIZED_SUFIX image_path = IMAGES_FOLDER + File.basename(resized_url) if !File.file?(image_path) image_to_resize = MiniMagick::Image.open(IMAGES_FOLDER + File.basename(image_url)) image_to_resize.resize('612x612') image_to_resize.format "png" image_to_resize.write(image_path) local_image = File.basename(resized_url) else puts "Skipping resizing of image: #{resized_url}" end end # Replace relative url on markdown file if !local_image.nil? && image_url != local_image contents = contents.gsub(image_url,local_image) end end end end puts(file) # Step 3: replace the file itself File.unlink(file) File.open(file, "w", encoding: "UTF-8") { |file| file.puts contents } end end localizer = Localizer.new('_posts', 'images') localizer.localize_images