Posts Tagged ‘ruby’

五月一号

05月 1, 2010

今天值得说的事情挺多的。首先,Ubuntu 10.04发布以后,Sun JDK 被放到了partner 仓库里,要使用Sun JDK,添加这个仓库:
sudo apt-add-repository “deb http://archive.canonical.com/ lucid partner”

这是悲剧的开始,早晨七点四十起床,添加了这个仓库,把机器上的Sun JDK升级到6u20,为此到了八点三十五才出门。现在没有自行车不比从前了,等公交加上下来走到公司最后九点零六分打上卡。进了办公室一看大家整整齐齐地坐着了,这才听到悲剧:三薪工作日不能迟到,否则只算半天。就为了6分钟,一天半的工资没了。这事现在想起来我都郁闷,发自内心的郁闷啊。

在上班的公交车上恰好收到邮件,是rubyforge的更新,昨天提交的patch已经被接受了,放进了svn仓库,会随Alexandria的0.6.6版本发布。项目的负责人修改了代码,把我那些\t都换成了空格。另外,豆瓣的API接口是json格式的,解析需要依赖libjson-ruby1.8这个库,这段代码被负责人修改了,真的很神奇,原来json可以就这样被转换成yaml
[cc lang="ruby"]
def json2yaml(json)
# insert spaces after : and , except within strings
yaml = json.gsub(/(\:|\,)([^A-Za-z\/\\])/) do |match|
“#{$1} #{$2}”
end
yaml.gsub!(/\\\//, ‘/’) # unescape forward slashes
yaml
end
[/cc]
震惊了,不过我之前也太了解yaml,也许这个技巧在ruby世界是众所周知的吧。这下json模块的依赖就可以去除了,真没想到会这么简单。

想起来我给另一个开源软件fantasdic提交的google translate的patch,作者已经认可了,但是至今还没有被加进仓库里。这位作者在日本读书不亦乐乎看来心思已经完全不在这个项目上了。

下午下班回家又是坐公交车,越想越忿忿,晚上又去买了一辆新自行车,于是今天基本上就算是白干了。之前的自行车被偷,多半的原因是后来买的锁强度太弱。先前的锁呢又因为生锈最后没法用了,归根结底,还是我保养地不好。其实保养锁很简单的,买个肉包,把里面的肉吃掉之后,那钥匙蘸蘸剩下的油,放到锁眼里捅捅就成。

五一了,世博了。和奥运会一样,还是和我没有什么直接关系。

Douban provider for Alexandria

04月 30, 2010

Alexandra is a desktop book collection manager on gnome written in ruby. With an extensible architecture, Alexandria uses different sources to retrieve book’s data, including Amazon and many local sites.

Douban.com is considered to be most applicable data source for books published in Chinese. So I write this provider according to Alexandria’s SPI. Now it’s possible to add Chinese books and manage reading lists.

alexandria

Now the code can be found in Alexandria’s bug tracker:
http://rubyforge.org/tracker/index.php?func=detail&aid=28160&group_id=205&atid=865

However, the patch file of book_providers.rb in that list is for svn trunk head version only. To use it with currently stable version of Ubuntu, first, make sure you have Alexandria version 0.6.5-0ubuntu1 and libjson-ruby1.8 installed.

Download douban.rb from rubyforge:
http://rubyforge.org/tracker/download.php/205/865/28160/4923/douban.rb
Copy the file to /usr/lib/ruby/1.8/alexandria/book_providers/ with super user privileges.
Use this patch to /usr/lib/ruby/1.8/alexandria/book_providers.rb
[cc lang="ruby"]
310a311,323
< begin
< begin
< require 'json'
< rescue LoadError
< require 'rubygems'
< require 'json'
< end
< require 'alexandria/book_providers/douban'
< rescue LoadError =< ex
< log.error{ex}
< log.warn {'Fail to load douban as provider'}
< end
<
[/cc]

Feel free to report issue here.

Patch for Fantasdic Google Source

02月 2, 2010

I found fantasdic a great powerful dictionary tool with friendly UI and supports multiply sources. Unfortunately, this project seems to be no longer maintained. The latest version is 1.0-beta7.
fantasdic-google

The google translate source was created in 2007. As the google translate service page changed, this module doesn’t work any more, so I just picked up my vim then created this patch for those still want to use it.

This patch has dependency with ruby’s json module, so before you apply it, run:
sudo gem install json
or
sudo apt-get install libjson-ruby1.8

Download the patch at:
https://bugzilla.gnome.org/attachment.cgi?id=152835

Patch it (Ubuntu installation as example):
cd /usr/lib/ruby/1.8/fantasdic/sources/
sudo patch google_translate.rb /home/sun/google_translate.rb.diff

Restart fantasdic, then your get it works! And this bug is tracked at:
https://bugzilla.gnome.org/show_bug.cgi?id=605641

Using Yan in Ruby Web Application

12月 21, 2009

I will show you the usage of Yan captcha service. In this tutorial, it’s based on a simple ruby web application of the Sinatra web framework.

Before we start to use the service, it is necesary to get Yan running. Download the code from the project page, then build and run it with maven:
mvn jetty:run

To enable the application to use Yan, we have to register our application to get an API Key. If you use Yan 0.3, there is a secret registration page at http://localhost:8080/yan/reg.jsp The page is protected by HTTP Basic Authentication, the username and password are store in ‘realm.properties’ which is considered to locate in the root directory. Open the file you can see the plain text username and password. If you are running the latest development version, there is no long any UI for API Key creation, but restful interface. This won’t be hard to you, pickup your tools such as curl or poster (a firefox extension) to send a HTTP request. Take curl as example, do it like this:
curl -X PUT “http://localhost:8080/yan/apikey/” -d “SinatraTestApp” -u “username:password”

If it works, you will get a line of json:
{“apikey”:”b251b0dc2eed31cac38555b61d4fa6a453923bfd”,”appName”:”SinatraTestApp”}
Save this apikey.

Sinatra is generally considered to be the world’s lightest and smallest web framework. And our application is rather simple. Just check the code:

require "rubygems"
require "sinatra"
require "net/http"
require "yaml"

apikey='b251b0dc2eed31cac38555b61d4fa6a453923bfd'

get '/' do
	conn = Net::HTTP.new('localhost', 8080)
	q = "ip=#{@env['REMOTE_ADDR']}&apikey=#{apikey}&alt=yaml&mode=0"
	resp, data = conn.get("/yan/ticket?#{q}")
	@ticket = YAML::load(data)
	haml :sinatra_captcha
end

post '/' do
	conn = Net::HTTP.new('localhost', 8080)
	q = "ip=#{@env['REMOTE_ADDR']}&apikey=#{apikey}&key=#{params['key']}&code=#{params['captcha']}"
	resp, data = conn.get("/yan/validate?#{q}")
	data
end

use_in_file_templates!
__END__

@@ sinatra_captcha
%html
	%head
		%title Yan Captcha on Sinatra
	%body
		%form{:action=>"/", :method=>"post"}
			%p
				Username:
				%input{:name=>"username", :type=>"text"}
			%p
				Password:
				%input{:name=>"password", :type=>"password"}
			%p
				Captcha:
				%img{:src=>@ticket['url']}
				%br
				%input{:name=>"captcha", :type=>"text"}
				%input{:name=>"key", :type=>"hidden", :value=>@ticket['key']}
				%input{:type=>'submit'}

There are two parts of this application: ruby code and haml. I just use in-file-template for convenience. We define a get handler and a post handler on the path ‘/’. The get handler will request a ticket from Yan which contains captcha image url and ticket key. The post handler will extract user input and submit the Yan’s validator and return user the result. And the HAML code is template for page rendering after GET request.

Maybe you need to install sinatra and some dependency:
sudo gem install sinatra haml

Run the code with a build-in WEBrick
ruby sinatra-yan.rb

Browse to the default url, test it:

For another similar tutorial using python, check Yan’s wiki page:
http://bitbucket.org/sunng/yan/wiki/SampleCode

Thank you for your support. btw, today is my dear girl friend’s birthday, I just wish her happy everyday.

GeoHash

09月 19, 2009

今天偶然看到一个Ruby的GeoHash库,功能非常简单,就是将经纬度坐标哈希成字符串,并且,利用这个字符串可以粗略地比较两点的距离。这个库的代码host在GitHub上,要安装,需要将github加入gem:
sudo gem sources -a http://gems.github.com
sudo gem install davotroy-geohash

用法,irb:
irb(main):001:0> require ‘rubygems’
=> true
irb(main):002:0> require ‘geohash’
=> true
irb(main):003:0> GeoHash.encode(32.168, 118.54)
=> “wtsr12n0nj”
irb(main):004:0> GeoHash.decode(‘wtsr12n0nj’)
=> [32.168, 118.54]

代码可以从github上获得
git clone git://github.com/davetroy/geohash.git

GeoHash的核心部分用C实现,仔细看一下可以发现是一个四叉树的结构:

[codesyntax lang="c"]
#define BASE32	"0123456789bcdefghjkmnpqrstuvwxyz"
static void encode_geohash(double latitude, double longitude, int precision, char *geohash) {
	int is_even=1, i=0;
	double lat[2], lon[2], mid;
	char bits[] = {16,8,4,2,1};
	int bit=0, ch=0;

	lat[0] = -90.0;  lat[1] = 90.0;
	lon[0] = -180.0; lon[1] = 180.0;

	while (i < precision) {
		if (is_even) {
 			mid = (lon[0] + lon[1]) / 2;
 			if (longitude > mid) {
				ch |= bits[bit];
				lon[0] = mid;
			} else
				lon[1] = mid;
		} else {
			mid = (lat[0] + lat[1]) / 2;
			if (latitude > mid) {
				ch |= bits[bit];
				lat[0] = mid;
			} else
				lat[1] = mid;
		}

		is_even = !is_even;
		if (bit < 4)
			bit++;
		else {
			geohash[i++] = BASE32[ch];
			bit = 0;
			ch = 0;
		}
	}
	geohash[i] = 0;
}

[/codesyntax]

可惜在学校的时候没有看到这么精致的代码。


加关注

Get every new post delivered to your Inbox.