Archive for October 17th, 2006

Rake task to prepare test database from migrations

To use your migrations for preparing test database create a file testdb.rake
in the directory lib/tasks.
Now add the following code in the lib/tasks/testdb.rake file…

module Rake
  module TaskManager
    def redefine_task(task_class, args, &block)
      task_name, deps = resolve_args(args)
      task_name = task_class.scope_name(@scope, task_name)
      deps = [deps] unless deps.respond_to?(:to_ary)
      deps = deps.collect {|d| d.to_s }
      task = @tasks[task_name.to_s] = task_class.new(task_name, self)
      task.application = self
      task.add_comment(@last_comment)
      @last_comment = nil
      task.enhance(deps, &block)
      task
    end
  end
  class Task
    class << self
      def redefine_task(args, &block)
        Rake.application.redefine_task(self, args, &block)
      end
    end
  end
end

def redefine_task(args, &block)
  Rake::Task.redefine_task(args, &block)
end

namespace :db do
  namespace :test do

    desc 'Prepare the test database and migrate schema'
    redefine_task :prepare => :environment do
      Rake::Task['db:test:migrate_schema'].invoke
    end

    desc 'Use the migrations to create the test database'
    task :migrate_schema => 'db:test:purge' do
      ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
      ActiveRecord::Migrator.migrate("db/migrate/")
    end

  end
end

To prepare the test database from migrations run this command
$ rake db:test:migrate_schema

3 comments October 17, 2006

How to improve the image quality and generate random string image in the plugin validates_captcha

Hello Everyone !!
I have released a captcha plugin Simple Captcha. It is really simple to implement, and provides a cool feature of multiple styles of images.


Previous post about improving validates_captcha’s images


Validates captcha is a good plugin to implement captcha in your rails application.
However i found that there is repetition of the string of the image and the quality of image is not that good. To get a good quality image and random string
something like this

replace the code of the file /vendor/plugins/validates_captcha/lib/captcha_challenge.rb with the following code…


require 'digest/sha1'

module AngryMidgetPluginsInc #:nodoc:

	# CaptchaChallenge
	class CaptchaChallenge

		include CaptchaConfig
		extend CaptchaConfig

		DEFAULT_TTL = 1200#Lifetime in seconds. Default is 20 minutes.

		attr_reader :id, :created_at
		attr_accessor :ttl

		def initialize(options = {}) #:nodoc:
			generate_id

			options = {
				:ttl => config['default_ttl'] || DEFAULT_TTL
			}.update(options)

			self.ttl = options[:ttl]
			@created_at = Time.now

			self.class.prune
		end

		# Implement in subclasses.
		def correct? #:nodoc:
			raise NotImplementedError
		end

	private

		def generate_id #:nodoc:
			self.id = Digest::SHA1.hexdigest(Time.now.to_s+rand.to_s)
		end

		def id=(i) #:nodoc:
			@id = i
		end

		def write_to_store #:nodoc:
			store.transaction{
				store[:captchas] = Array.new unless store.root?(:captchas)
				store[:captchas] << self
			}
		end

	class << self

		# Removes old instances from PStore
		def prune
			store.transaction{
				if store.root?(:captchas)
					store[:captchas].each_with_index{|c,i|
						if Time.now > c.created_at+c.ttl
							store[:captchas].delete_at(i)
						end
					}
				end
			}
		end#prune
	end#class << self

	end

	# A CAPTCHA challenge where an image with text is
	# generated. A human can read the text with relative
	# ease, while most robots can not. There are accessibility
	# problems with this challenge, though, as people
	# with reduced or no vision are unlikely to pass the test.
	class CaptchaImageChallenge < CaptchaChallenge

		WORDS = 'gorilla costume, superman, banana bender, chuck norris, xray vision, ahoy me hearties,
				 chunky bacon, latex, rupert murdoch, clap your hands, year 2000,
				 sugar coated, coca cola, rastafarian, airbus a380'.split(/,s+/)
		DEFAULT_DIR = 'captcha'#public/images/captcha
		WRITE_DIR = File.join(RAILS_ROOT, 'public', 'images')
		DEFAULT_FILETYPE = 'jpg'

		attr_reader :image
		attr_accessor :string, :dir, :filename, :filetype

		# Creates an image challenge.
	  def initialize(options = {})
			super

			options = {
				:string => config['words'] ? config['words'][rand(config['words'].size)] : WORDS[rand(WORDS.size)],
				:dir => config['default_dir'] || DEFAULT_DIR,
				:filetype => config['default_filetype'] || DEFAULT_FILETYPE
			}.update(options)

            self.string = Digest::SHA1.hexdigest(Time.now.to_s)[0..4].upcase #options[:string]
            self.dir = options[:dir]
            self.filetype = options[:filetype]
            self.filename = options[:filename] || generate_filename
            write_to_store
          end

		# Generates the image.
		def generate(options = {})
			options = {
				:fontsize => 50,
				:padding => 20,
				:color => '#000',
				:background => '#fff',
				:fontweight => 'bolw',
				:rotate => true
			}.update(options)

			options[:fontweight] = case options[:fontweight]
				when 'bold' then 700
				else 400
			end

			#added
			text = Array.new
			0.upto(4) do |i|
				text[i] = Magick::Draw.new
				text[i].pointsize = options[:fontsize]
				text[i].font_weight = 600 #options[:fontweight]
				text[i].fill = 'black' #options[:color]
				text[i].gravity = Magick::CenterGravity
				text[i].rotation = (rand(2)==1 ? rand(30) : -rand(30)) if options[:rotate]
			end

                  metric = text[2].get_type_metrics(self.string)
                  #add bg
		  canvas = Magick::ImageList.new
		  fill = Magick::HatchFill.new('white','black')
		  x = metric.width+options[:padding]
		  y = metric.height+options[:padding]

		  #ADDING NOISE

		  img1 = Magick::Image.new(x,y,fill)
		  gc = Magick::Draw.new
		  gc.stroke_linejoin('round')
		  gc.stroke('black')
		  gc.stroke_width(1)
                  100.times do |i|
                    x1 = rand(x)
                    y1 = rand(y)
                    gc.circle(x1,y1,x1.next,y1)
                  end
                  gc.draw(img1)
                  canvas << img1
                  0.upto(4) do |i|
				canvas << Magick::Image.new(metric.width+options[:padding], metric.height+options[:padding]){
					self.background_color = '#000F'
					y_loc = rand(y)
				}.annotate(text[i], 0, 0, (i-2)*30, rand(y/4), self.string[i,1]) #.wave(5, 20)
		  end

		  canvas << Magick::Image.new(metric.width+options[:padding], metric.height+options[:padding]){
		    #changed
		    p = Magick::Pixel.from_color(options[:background])
		    p.opacity = Magick::MaxRGB
		    self.background_color = p
		  }  #.add_noise(Magick::LaplacianNoise)

			self.image = canvas.flatten_images.blur_image(1)
		end

		# Writes image to file.
		def write(dir = self.dir, filename = self.filename)
			self.image.write(File.join(WRITE_DIR, dir, filename))
		end

		# Determine if the supplied +string+ matches
		# that used when generating the image.
		def correct?(string)
			string.downcase == self.string.downcase
		end

		# The full path to the image file, relative
		# to <tt>public/images</tt>.
		def file_path
			File.join(dir,filename)
		end

	class << self

		# Deletes old image files. Also calls CaptchaChallenge.prune
		def prune
			store.transaction{
				if store.root?(:captchas)
					store[:captchas].each_with_index{|c,i|
						if Time.now > c.created_at+c.ttl
							if File.exists?(File.join(WRITE_DIR, c.file_path))
								begin
									File.unlink(File.join(WRITE_DIR, c.file_path))
								rescue Exception
								end
							end
						end
					}
				end
			}
			super
		end#prune
	end#class << self

	private

		def generate_filename #:nodoc:
			self.id+'.'+self.filetype
		end

		def image=(i) #:nodoc:
			@image = i
		end

	end

end

visit Here to view the customized use of the plugin validates_captcha in RoR.

22 comments October 17, 2006


Ruby on Rails

Contact

sur.max(at)gmail.com

Seems Useful

 

October 2006
M T W T F S S
« Sep   Nov »
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

Recent Posts

Power Shots

Untitled

midnight city still

PPPA: Professional Puppy Photographers of America.

Untitled

Mortuary

Palm trees at night

Three Impala drink at Kruger waterhole

Untitled

Untitled

morning windows

More Photos

Zipped

Subscribe