class RussianPost::Captcha
Attributes
patterns[R]
Public Class Methods
for_data(data, patterns = nil)
click to toggle source
# File lib/russian_post/captcha.rb, line 18 def for_data(data, patterns = nil) RussianPost::Captcha.new(nil, data, patterns) end
for_url(url, patterns = nil)
click to toggle source
# File lib/russian_post/captcha.rb, line 14 def for_url(url, patterns = nil) RussianPost::Captcha.new(url, nil, patterns) end
new(url = nil, data = nil, patterns = nil)
click to toggle source
# File lib/russian_post/captcha.rb, line 58 def initialize(url = nil, data = nil, patterns = nil) # private constructor @url = url @data = ChunkyPNG::Image.from_blob(data) if data @patterns ||= RussianPost::Captcha::Patterns.built_in end
Public Instance Methods
image()
click to toggle source
# File lib/russian_post/captcha.rb, line 24 def image @data ||= fetch_image end
recognize()
click to toggle source
# File lib/russian_post/captcha.rb, line 36 def recognize @recognize ||= recognize! end
recognize!()
click to toggle source
# File lib/russian_post/captcha.rb, line 40 def recognize! captcha_image = grayscale(image) results = {} for x in 0..captcha_image.width - 2 for y in 0..captcha_image.height - 2 result = patterns.find(captcha_image, x, y) results[x] = result if result end end Hash[results.sort].values end
text()
click to toggle source
# File lib/russian_post/captcha.rb, line 28 def text @recognized_text ||= prepare_text(recognize) end
valid?()
click to toggle source
# File lib/russian_post/captcha.rb, line 32 def valid? text.size == 5 end
Private Instance Methods
fetch_image()
click to toggle source
# File lib/russian_post/captcha.rb, line 75 def fetch_image raise "URL not specified" unless @url data = Excon.get(@url).body unless data.start_with?("\x89PNG".force_encoding("ASCII-8BIT")) # not png header if data =~ /<input id=\"key\" name=\"key\" value=\"([0-9]+)\"\/>/ # tough security huh data = Excon.post(@url, body: "key=#{$1}").body end if data =~ /Object moved/ # faulty captcha raise "Russian Post captcha service error" end if data.include?("window.location.replace(window.location.toString())") return fetch_image # start from beginning end end ChunkyPNG::Image.from_blob(data) end
grayscale(captcha_image)
click to toggle source
# File lib/russian_post/captcha.rb, line 69 def grayscale(captcha_image) captcha_image.pixels.map! { |color| color = ChunkyPNG::Color.grayscale_teint(color); color = (color >= 255) ? 255 : 0 ; color } captcha_image end
prepare_text(results)
click to toggle source
# File lib/russian_post/captcha.rb, line 64 def prepare_text(results) captcha_text = results.map(&:character).join('') captcha_text.size == 5 ? captcha_text : raise(RecognitionError, "Unable to recognize captcha") end