Subheader

Lazy Programmer's Blog

Pages

Showing posts with label rails. Show all posts
Showing posts with label rails. Show all posts

Friday, July 22, 2016

Rails Paperclip and SVG files

Paperclip has unpleasant handling of SGV files, so it corrupts SVG XML file, and finally uploaded original file will have just header.

Temporary dirty solution is to replace original SVG file. Lets assume we need to store jpg/png/gif/svg image, which can have thumbnail.

Model
class Image < ActiveRecord::Base
  has_attached_file :file,  styles: { thumb: {processors: [:image_thumb]}}
  validates_attachment_content_type :file,
    content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif", "image/svg+xml"]

  attr_accessor :tmp_stage_file_name
    attr_accessor :tmp_stage_file_ext
    before_post_process :save_staged_file
    after_save :replace_original_file

  def save_staged_file
        if (path = file.staged_path)
            if (file.content_type == 'image/svg+xml')               
                @tmp_stage_file_name = File.join("/tmp", SecureRandom.uuid)
                @tmp_stage_file_ext = File.extname(path)
                FileUtils.cp(path, File.join("/tmp", "#{tmp_stage_file_name}#{tmp_stage_file_ext}"))
            end
        end
    end

    def replace_original_file
        if !file.blank? && !tmp_stage_file_name.blank?
            path = File.join("/tmp", "#{tmp_stage_file_name}#{tmp_stage_file_ext}")
            if File.exist? path
                FileUtils.cp path, file.path
                FileUtils.rm path, force: true
            end
        end
        @tmp_stage_file_name = nil
        @tmp_stage_file_ext = nil
    end
end
Image Processor
lib/paperclip_processors/image_thumb.rb

module Paperclip
    class ImageThumb < Processor
        HEIGHT = 320
        WIDTH = 320
        def initialize file, options = {}, attachment = nil
      super
      @file = file
      @instance = options[:instance]
      @current_format   = File.extname(@file.path)
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(file.path, File.extname(file.path))
            @geometry = options[:geometry]
    end

    def make
      geometry = Paperclip::Geometry.from_file(@file)
      filename = [@basename, @current_format || ''].join
      dst = TempfileFactory.new.generate(filename)

            begin
                cmd = file.content_type != 'image/svg+xml' ?
                    %Q(convert '#{file.path}' -resize '#{WIDTH}x#{HEIGHT}^' -gravity 'center' -crop '#{WIDTH}x#{HEIGHT}+0+0' +repage '#{dst.path}') :
                    %Q(rsvg-convert -a -w #{WIDTH} -h #{HEIGHT} -f svg '#{file.path}' -o '#{dst.path}')
                Paperclip.run(cmd)
            rescue
                raise Paperclip::Error, "There was an error processing the thumbnail for #{@basename}" if @whiny
            end
      dst
    end
    end
end

Friday, May 6, 2016

How to install just PostgreSQL client tools on Windows and use it in rails application

Since in latest installers for PostgreSQL support for custom components is removed, installer will install both client tools and PostgreSQL server.

Solution:

Step 1. Install ruby
I like RubyInstaller

Step 2. Install rails
I like RailsInstaller

Step 3. Download PostgreSQL binary package
http://www.enterprisedb.com/products-services-training/pgbindownload
Lets copy files into
C:\Program Files\PostgreSQL

Step 4. Install gem pg
gem install pg -- --with-pg-config="C:\Program Files\PostgreSQL\9.1\bin"
Now we can use PostgreSQL client tools in rails application

Monday, March 14, 2016

Ajax File Upload using JQuery in Rails

There are a lot of JQuery plugins that provide functionality of ajax file upload. In case when we don't need to visualize upload progress but simple need just a possibility to perform ajax file upload I usually use remotipart gem https://github.com/JangoSteve/remotipart

Step 1.
Append following gems in our Gemfile:
gem 'jquery'
gem 'jquery-ui-rails'
gem 'remotipart', '~> 1.2'

Step 2.
Include JQuery, JQuery UI and remotipart in your application.js
//= require jquery
//= require jquery.ui.all
//= require remotipart

Step 3.
Add remote parameter to your form
= form_for user, authenticity_token: true, :multipart => true, data: {remote: true} do |f|

Here is my simple CRUD rails application that implements user creation with avatar uploading.

Link to github page https://github.com/serghei-topor/ajax-file-upload-example-rails
Installation:
Step 1: Install system dependencies (Imagemagick and PostgreSQL)
sudo apt-get install -y imagemagick libmagickwand-dev rsvg-convert exiv2 libpq-dev

Step 2: Clone project from github
git clone https://github.com/serghei-topor/ajax-file-upload-example-rails.git

Step 3: Run migrations
rake db:migrate