1/09/2009

ReCAPTCHA 與 ReCAPTCHA Rails Plugin

我們不管是註冊,或是去便當狗下載東西,都會有一張圖裡面有字,然後要你 keyin 正確的字。那個東西叫做 CAPTCHA。 CAPTCHA 是 ”Completely Automated Public Turing test to tell Computers and Humans Apart”的縮寫,主要用途是為了防止 robot Spam所做的手段。我看過最討厭,最難懂得 CAPTCHA 就是 Google 的 CAPTCHA,每次看都要硬猜個一兩次才會對,大概是他們整天被 Spam 攻擊,只好連真人都開始防堵 XD

而什麼是 ReCAPTCHA 呢? ReCAPTCHA 是卡內基美隆大學的一項計畫,由卡內基美濃學院資訊科學系執行。主要目的是為了加快實體文本數位化而作的一個手段,一般來說實體文本數位化需要的是數位掃描的技術,但是還是有很大量的書籍裡面的字礙誨難懂,有可能是紙張變質,也有可能是以前人的書寫習慣不公整(就是講我XD),這個時候就需要人力去辨識字的內容,並且給予機器正確的 return,順便 training 數位技術 Algorithm。很可惜的是,人力是要錢的。所以他們想出一個聰明到嚇死人的方式來處理這個問題。

他們開發了一個網站,叫做 ReCAPTCHA 。裡面提供 CAPTCHA API ,讓網站開發者當需要 CAPTCHA 的技術時候,可以直接 Implement 這個 API,而不需要依賴自己重新開發 CAPTCHA 技術。他們並且號招很多志願者開發各種語言版本的 API,來加速網站開發者 implement ReCAPTCHA的速度。以下是 ReCAPTCHA 的截圖



那為何他要免費提供這樣的服務呢?我們來仔細看他的技巧來自於 CAPTCHA 圖片本身,ReCAPTCHA 的圖片都是兩個英文字



左邊的字 following 是他們已經確認掃描正確的字,右邊的 finding 是他們還無法用掃描確定意義的字。當使用者在 keying 認證碼的同時,他只要確定左邊的「following」是正確的,他們就認為是正確的 input,予以放行,但是使用者不是也 keyin 右邊的字嗎?那那個 input,ReCAPTCHA網站就視為你順手幫我做的影像校正,存到資料庫裡面。網站開發者免費得到 CAPTCHA 技術,ReCAPTCHA 獲得數以百萬記的免費人力幫忙校正,是個典型的雙贏局面。

至於 Ruby 裡面有沒有 ReCAPTCHA API 呢?當然有。ReCAPTCHA for Ra ils 主頁在此。安裝方式就是


ruby script/plugin install git://github.com/ambethia/recaptcha.git



安裝完成之後,你必須要先去 ReCAPTCHA 網站註冊,他會給你一個 PUB key 跟 Private key,將他記錄在 Rails 的 config/enviroment.rb 裡面




1
2
ENV['RECAPTCHA_PUBLIC_KEY'] = "public_key_goes_here"  
ENV['RECAPTCHA_PRIVATE_KEY']= "private_key_goes_here"


接下來就是使用 ReCAPTCHA 啦,你要將 ReCAPTCHA 放在你需要的地方,這邊唯一要注意的地方在於你必須要放在 form 裡面



1
<%= recaptcha_tags %>  



接下來要驗證對方 keyin 的認證碼正不正確,我們只需要在相關的 controller 放入




1
2
3
4
5
if verify_recaptcha  
#正確的處理方式
else
# 錯誤的處理方式
end


然後,沒啦,很簡單吧!!!

12/26/2008

File_Column 在 Rails 2.2 遇到問題以及解法

這裡找到的解法,File_column 在升級 Rails 2.2 會遇到問題

uninitialized constant FileColumn::ClassMethods::Inflector 


解決方式就是找到 vender/plugins/file_column/lib/file_column.rb 的 619行

my_options = FileColumn::init_options(options,   
Inflector.underscore(self.name).to_s,
attr.to_s)


改成

my_options = FileColumn::init_options(options,
ActiveSupport::Inflector.underscore(self.name).to_s,
attr.to_s)


即可。主要原因是 Rails Core 漸漸有 Namespace 概念(不是本來就要有了嗎XD),所以之前可以 work 的 plugin code 現在都要修改成比較好的寫法。

12/24/2008

金剛合體:Merb 將要 merge 到 Rails 3

我以為 Rails 2.2 已經很有創意了,弄出很多新東西(or 應該做的東西) ,Rails 3 到底要做啥東西才能夠讓人家驚訝了呢?噹噹,我發現到 Rails 還是嚇到我了 。

Big news 就是 Merb 跟 Rails 3 預計在 2009 的 Rails conf Merge 起來,Merb 作者 wycats( Yehuda Katz)會加入 Rails Team。請注意,我知道很瘋狂,不過這個消息已經經過 Rails And Merb 雙方證實了。

DHH 指出這次的 Merge 有幾點工作要做

  1. Rails core:Rails 是一個 full stack framework ,不過他要參考 merb ,讓人很簡單的做出 rails myapp–core 和 rails myapp—flat
  2. 效能強化
  3. Framework 解構:雖然 Rails 預設依舊是 ActiveRecord 當 ORM,不過你也可以選擇 data mapper,Sequel,Template 可以選擇 HAML,AJAX 可以選擇 jquery
  4. Rigorous API:反正就是要解決 Rails 一升級 plugin 就炸掉的問題

怎麼看起來像是又生出一個 Merb ?

我來猜猜,DHH 認為 Merb 社群長久以來的堅持是對的,而 Rails 社群漸漸走錯路, DHH 眉頭一皺,認為案情並不單純,利用自己還很龐大的力量吃掉 Merb ,然後順便導正 Rails 該走的路。

It is not good news , and it is also not bad news,It's AMAZING news。


12/22/2008

Ruby Memory Leak 巨大問題以及解決方式

Ruby Memory Leak 一向是一個難以解決的議題,不過在今年 11月12日的 Mailing List 裡面有人提出一個重要的問題, Ruby 的 callcc 在使用中產生相當明顯的 Memory Leak。後來有高手 Brent Roman 發表他的發現。他原本再 ARM CPU 上面開發他的 Ruby Robot 程式(Ruby 1.6.8),他的機器人上面只有 32 MB 的 Memory,不過他的 Ruby 程式一天就會吃掉 20MB 的 Memory,經過他的 hack ,現在他的 Ruby 程式已經穩定在 10MB 以下,他發現 Ruby Memory Leak 很大部分在於 pointer ,跟 callcc 的使用上,Javaeye 上面有對於這個問題的詳細中文翻譯


Matz 知道之後,相當鼓勵 Brent 將他的 Patch 放到 Ruby 上面,如今他的 Patch 終於發佈,他是根據 Ruby 1.8.7-p72 做的 Patch ,又由於他在 Monterey Bay Aquarium Research Institute工作,所以叫做 1.8.7-p72 MBARI Patch,目前處於 Alpha 版本。他發現經過他的 hack 之後,對於 Memory Leak 上有相當大的解決。根據他的用 Ruby 預設的 Test Case 的結果,他發現 Memory 消耗從 97MB 降低到 57 MB,JavaEye 也利用他們的程式做測試,Javeeye Fcgi Memory 消耗量從 129MB 降低為 99MB。


相當不錯的結果,期待納入 Ruby 1.8.7 的那一天。


12/16/2008

Rails 2.2 在 Windows 上面有關 mysql Gem 的問題

今天要幫公司同事灌 Windows 上面 Rails ,發現安裝 mysql gem 出了點問題 ,本來是不用管,直接使用 Rails 附帶的 Mysql, 不過自從 Rails 2.2 之後,Rails 原本附帶的 mysql adaptor 已經移除掉adaptor,所以被迫得安裝 MySQL Gem 。

The bundled mysql.rb driver has been removed from rails 2.2. Please
install the mysql gem and try again: gem install mysql."
當我 gem i mysql,本來是沒問題的,不過現在不知道 gemspec 那裡改壞了,導致出現問題
Installing ri documentation for mysql-2.7.3-x86-mswin32...
Installing RDoc documentation for mysql-2.7.3-x86-mswin32...
ERROR: While generating documentation for mysql-2.7.3-x86-mswin32
... MESSAGE: Unhandled special: Special: type=17, text=""
... RDOC args: --op
所以第一個問題解法就是不搞 RDOC,直接使用 gem i mysql --no-ri --no-rdoc 安裝

當我以為已經解決的時候,沒想到出現第二個 Error
This error occurred while loading the following files: mysql
靠,Rails 2.2 + Windows 還真多災多難,解決方式根據這裡,裡面說到要把 MySQL 帶的 libmysql.dll 複製一份過去到 ruby\bin 底下
copy mysql\bin\dll\libmysql.dll ruby\bin\
我使用的是 Instant Rails ,所以 MySQL 跟 Ruby 都放在同一個資料夾下面,如果安裝方式不同請自行處理。


10/26/2008

Rails 2.2 :多個願望一次達成...

購物專家:來來,我們現在請到 Rails 副總來本購物台,想請問副總對於這次 Ruby on Rails 2.2 來本台銷售,帶來了什麼好康。

副總:這次的 Rails 2.2 可以說是本 Rails 產品史上最大的升級,可以說是把所有想的到聽的到看的到的問題都一次解決,保證這次不買你就是笨蛋,還去寫 PHP 或是 Java 只能祝福你。

購物專家:啥,那麼可怕,那我想問問,有關之前被人詬病的 Rails 國際化的部份有何加強。

副總:記得上次我們來的時候怎麼講的?Rails 要國際化必須要 Gettext 或是 Plugin 來解決對不對。今天帶來的第一個優惠, Rails 2.2 直接內建 i18n 給你。如果有問題的話,請到Rails i18n來看看怎麼實作。基本上是寫一個 yaml 就可以解決了。

(罐頭歡呼聲)

購物專家:什麼,直接內建 i18n ,那其他 Framework 不是少了一個古老的暴點可以笑 Rails 了嗎?你們上面業績衝的很兇歐,優惠送那麼大。那以前最讓人詬病的效能問題呢?

副總:抱歉,其他家公司,你們災洗了。我們這次直接升級到 Ruby 1.9,讓你們享受 19 倍的效率提昇。(註:購物台都是隨便唬爛的,有提昇是沒錯,有沒有 19 倍就不知道XD)

(罐頭歡呼聲)

購物專家:什麼什麼,你們直接支援效率打敗 Python 2.5 的 Ruby 1.9 呀,那不就是筆記型電腦加 Ram 再加 ssd 這樣誇張歐。這樣你們不會獲利下降嗎?

副總:沒關係,只要可以服務購物台,我們可以流血犧牲

購物專家:導播,各位觀眾,我已經快受不了,那麼好的優惠,那麼好的內容只在今天的 XX 購物台。現在電話所有線路忙線中,請改撥語音專線可以優先訂購。副總,已經端出那麼多了,還有啥好康的?

副總:還有還有,我們改寫 ActiveRecord 了,支援 connection pool 摟,並且是 ThreadSafe 了。只要在 config/database.yml 裡面加上

development:
___adapter: mysql
___username: root
___database: sample_development
___pool: 100
___wait_timeout: 10

就等於以 100 connection 讓 model 讀讓你取,效能提昇直接上看 100倍 (註:購物台都是隨便唬爛的,有提昇是沒錯,有沒有 100 倍就不知道XD)

(罐頭歡呼聲)

購物專家:現在耳機傳來導播的聲音,現在我們備貨數量已經真的真的很少了,大家太踴躍了,記得撥打語音專線可以省一百塊歐。副總你們還有啥優惠嗎?

副總:我們加入了 HTTP 的 last modified since 的 support,讓上次沒有修改過的內容就直接回傳一個 empty response 回去。原本是要回傳幾百K的東西,現在至需要回傳 0 K ,效能提昇直接上看無限大(註:購物台都是.....算了,懶得講了XD )

(罐頭歡呼聲)
(罐頭歡呼聲)
(罐頭歡呼聲)

副總:ㄟㄟㄟ,導播,我的購物專家勒?

導播:他太激動了,回去學習 Ruby on Rails 了。

副總:ㄟㄟㄟ,那麼猴急,我還沒講完勒,http://guides.rubyonrails.org 上線了,可以直接上去看一些 online guilde。



言歸正題,此次的 Rails 2.2 真的是超乎想像的加碼再加碼,修正了很多以前的問題,也加入相當多新的功能。

1. i18n
2. Ruby 1.9
3. connection pool
4. thread safe
5. etag and last modified since

真的可以說是史上最大的升級 XD

6/25/2008

Python Hackthon 遭到保護動物組織的抗議

http://www.javaeye.com/news/2697

http://techfaux.com/2008/06/17/peta-targets-computer-programmers-with-string-of-bizarre-protests/

間單講就是好好的 Python Hackthon 聚會,闖入一堆 30位女生,突然全部脫光衣服,然後舉牌子「How many lives just for a coat?」,意思是要殺掉多少蛇才能有一件蛇皮大衣。

這些天兵似乎還不知道自己在幹麼,她們大聲疾呼「We know what they’re doing in there. They’re hacking pythons. It’s barbaric and we won’t leave until the last snake has been saved」,秀才遇到兵,有理說不清。


改天 Ruby 聚會也有一堆人進來抗議,「停止虐待採紅寶石的勞工」怎麼辦....



6/06/2008

Rails 2.1 新特色:打包 Gem

顧客:老闆, Web 2.0 網站一份,Rails 要 2.1 的,還有幫我加香菜,還有所有的 Gem Package 都要包在一起,要快點,等等 10分鐘要上 Production Server。

老闆:好好好,馬上來,要不要順便叫個啤酒呀?

Rails 2.1 加入了一個新功能 Gem Dependencies ,相當的優。像是上述需求,只需要下達

$ rake rails:freeze:edge
$ vi config/environment.rb
$ rake gems:unpack
$ rake gems:build
即可完成將 Rails 原始碼,Gems 原始碼包入到 Rails app folder 裡面,這樣 deploy 超方便呀。

以下是詳細解說

$ rake rails:freeze:edge
把現在的Rails Version 打包入 vender/rails/

$ vi config/environment.rb
把所有有關的 Gem package 加入設定檔

Rails::Initializer.run do |config|

# Require the latest version of haml
config.gem "haml"

# Require a specific version of chronic
config.gem "chronic", :version => '0.2.3'

# Require a gem from a non-standard repo
config.gem "hpricot", :source => "http://code.whytheluckystiff.net"

# Require a gem that needs to require a file different than the gem's name
# I.e. if you normally load the gem with require 'aws/s3' instead of
# require 'aws-s3' then you would need to specify the :lib option
config.gem "aws-s3", :lib => "aws/s3"
end



$ rake gems:unpack
把所有的 config 裡面設定相關的 Gem Package 都打包入 vender/gems/

$ rake gems:build
非一定要用,只是如果你相關的 gem package 不一定是純 Ruby Code,有些會相關一些 C Lib,這時候就可以用這個指令來 build native gems。



6/05/2008

Gettext 在 Rails 2.1 下面的問題

Gettext 1.19 遇到 Rails 2.1 會發生以下的問題
NoMethodError (undefined method `file_exists?' for #):


解決方式就是寫一個 config/initializers/gettext.rb

require 'gettext/rails'
module ActionView
class Base
delegate :file_exists?, :to => :finder unless respond_to?(:file_exists?)
end
end



重起即可。

5/01/2008

Rails 2.1 RC Release

Rails 學習之路最困難的一件事就是,社群活力太強,改版太快了。Rails 2.1 RC Release了。請到Rails最新時尚的 github 去取用。