RSpec demo1 : rails中使用RSpec入门

环境 : ruby 1.8.7 + rails 2.3.2

这一demo介绍rspec在rails中的入门 , 需要安装的依赖库 , 和执行过程 , 目录结构等

1, 安装依赖包 rspec 和 rspec-rails

>sudo  gem install rspec
>sudo gem install rspec-rails

安装结束后,>gem list r 查看r开头的gem包:

rspec (1.3.0)
rspec-rails (1.3.2)

rspec 包 是rspec的核心库 , rspec-rails 是把rspec集成到rails中 , 例如 支架 rspec_scaffold , rspec_model 等等

2,新建rails工程

>rails test_rspec -d mysql

3,修改 database.yml
注意 development 和 test 都要修改

4,建立数据库
同时建立 development 和 test 数据库
例如分别为 : test_rspec_development 和 test_rspec_test

5,支架生成MVC和rspec测试文件

>./script/generate rspec_scaffold user name:string

使用rspec_scaffold 比原来的 scaffold 支架 仅仅是多了 rspec部分, 在rails project 中在 spec 文件夹下

6, migrate

>rake db:migrate

6,测试

>rake spec

更多的关于spec的rake可以这样看下:

>rake -T spec

或者

>spec spec/models/user_spec.rb

直接执行某个 rspec 文件 测试 , 使用 spec 执行, 还可以加入一些参数 例如 :

>spec spec/models/user_spec.rb -f specdoc

输出 doc, 更多参数 >spec -h 查看

ref:
http://wenke.javaeye.com/blog/254496

ruby 抓取脚本

今天用 httpclient + hpricot 写了个备份我的blog的脚本 , 把图片 和文章都给抓了下来 , 由于没有备案 , 害怕有一天被和谐了 , 所以 还是早点备份一下为好 , 或者 以后自己 买了 VPS , 也好导入数据。

这只是一个简单的脚本 , 100 行左右就搞定了 , 更多的spider ,可以自由发挥 , 感兴趣的可以down下来研究研究 , 只是针对我的blog写的脚本 , 主要就是解析html这里不一样,其它差不多 , 核心代码:

require 'rubygems'
require 'open-uri'
require 'hpricot'
require 'fileutils'
require 'httpclient'
require 'md5'
 
def debug content
  File.open("./#{PREFIX_LOG}spide.log","a+") { |file| file.write("#{content}\t" + DateTime.now(:db).to_s + "\n" ) }
end
 
def blog post
  path = "./#{PREFIX_BLOG}#{post[:title]}.html"
  if !File.exist?(path)
    File.new(path,"w+")
    File.open(path,"a+") do |file|
      file.write(W3C + "\n#{post[:title]}\r" + "#{post[:pub_time]}\n\n" + "#{post[:content]}\n")
    end
  end
end
 
def spide url , page = 10
 
  page.times do |p|
    p = p+1
    next  if page_spided? url , p
    page_urls = page_url url , p  
    page_urls.each do |u|
      next if url_spided? u
      File.open("./#{PREFIX_LOG}url.log","a+") { |f| f.write("spide_url|#{u}\n") }
      post =  spide_detail u
      blog post
    end
 
  end
 
end
 
# 页面里所有的文章连接(title)
def page_url url , p
  urls = Array.new
  url = url + "/page/#{p}"
  File.open("./#{PREFIX_LOG}page.log","a+") { |f| f.write("spide_page|#{p}|#{url}\n") }
  client = HTTPClient.new
  html = client.get_content(url,UA)
  doc = Hpricot(html)
  doc.search("h2[@class=entry-title]>a")  do |a|
    urls << a['href']
  end
 
  urls
end
 
# 解析 HTML
def spide_detail url
  post = Hash.new
  debug "spide #{url}"
  client = HTTPClient.new
  html = client.get_content(url,UA)
  doc = Hpricot(html)
 
  # 文章标题
  title = doc.search("h2[@class=entry-title]").inner_text
  post[:title] = title
 
  #发布时间
  pub_time = doc.search("abbr").inner_text
  post[:pub_time] = pub_time
 
  imgs = Array.new
 
  doc.search("div[@class=entry-content]").search("img").each do |i|
    imgs <<  i['src']
  end
 
  save_image imgs
 
  #内容
  content = doc.search("div[@class=entry-content]").inner_html 
  #   content.gsub!(/src="[a-zA-z]+:\/\/[^\s]*/)
  post[:content] = content 
 
  post
 
end
 
 
def save_image imgs
 
  FileUtils.mkdir './images' unless File.directory?('./images')
 
  imgs.each do |url|
    begin
      uri = URI.parse(url)
      format = uri.path.split(".").last
      img_name = "#{MD5.hexdigest(url)}.#{format}"
 
      if File.exist?("./images/#{img_name}")
        debug "exist #{url}"
        return 
      end
 
      client = HTTPClient.new
      body = client.get_content(url,UA)
      if body
        File.open("./images/#{img_name}","w") { |file| file.write(body) }
      end
 
    rescue => err
      debug err.inspect
      return nil
    end
  end
 
end
 
def page_spided? url , p
  path = "./#{PREFIX_LOG}page.log"
  File.new(path,"w+") unless File.exists?(path)
  File.open(path,"r").each_line do |line|
    if line.index("spide_page|#{p}|#{url}")
      return true
    end
  end
  return false
end
 
def url_spided? url
  path =  "./#{PREFIX_LOG}url.log"
  File.new(path,"w+") unless File.exists?(path)
  File.open(path,"r").each_line do |line|
    return true if line.index("spide_url|#{url}")
  end
  return false
end

代码思路:
1,安装httpclient 和 hpricot gem包
httpclient 是ruby 的http 库 , 可以模拟浏览器的操作,例如post数据等等 , 其他你还可以用ruby自带的NET::HTTP 库 , 还有mechanize额外库等 ,hpricot 是用来解析 html 的

2,扒取指定的页 , 例如 http://www.wxianfeng.cn/page/2/ 把这一页 所有 文章的url给抓出来 , 然后再对这一页的所有文章url再 抓取 , 分析 , 例如 http://www.wxianfeng.cn/page/2/ 这一页有 http://www.wxianfeng.cn/2009/12/18/firefox-live-bookmark-rss-ticker-%E4%BA%86%E8%A7%A3%E6%9C%80%E6%96%B0%E5%AE%9E%E6%97%B6%E4%BF%A1%E6%81%AF/ 的一篇文章的url

3,然后循环抓取不同的页

4,上面用到的 “md5″ 库, 是为了给抓取的图片生成名字

5, 所有抓取的内容 , 保存在文件中

6, 注意记录log , 以便分析抓取到哪了, 第二次执行的时候 , 抓取过的url 就next

7………..

全部源码地址 :
http://github.com/wxianfeng/wxianfeng_cn_spider

Jquery div slider plugin contentSlider1.0

结合 easyslider 和 InnerFade , 写了个 div content slider , 这个是 div的形式 , 当然你也可以改为 ul , li的形式 ,

具有的功能:
> 自动循环
> 可以选择指定的图片(1,2,3,4)
> 选择后 , 继续循环 , 也可以设置 不继续循环 , 也可以设置只循环一次
> 有slide(滑动),fade(渐隐) 两种效果
> 可以调节 轮换速度 和单张图片的 暂停时间
> …..

兼容所有常用的浏览器

DEMO
http://www.blogjava.net/fl1429/archive/2010/03/01/314196.html

source:
http://github.com/wxianfeng/contentSlider

ref:
http://cssglobe.com/post/4004/easy-slider-15-the-easiest-jquery-plugin-for-sliding
http://medienfreunde.com/lab/innerfade/

will_paginate tips

0,安装
可以安装为gem 或者plugin形式

1,效率

  @words = SearchWord.paginate(:conditions => ["alphabet = ? ", char], :order=>"number desc",:page => params[:page] , :per_page=>100)
@words = SearchWord.find(:all,:conditions=>["alphabet = ? ",char],:order=>'number desc').paginate(:page=>params[page],:per_page=>100)

上面两句分页查询的代码看似一样大,其实差别很大,第二个的效率低于第一个,生成的sql是分别是这样的:

ELECT * FROM `search_words` WHERE (alphabet = 101 ) ORDER BY number DESC
 
SELECT * FROM `search_words` WHERE (alphabet = 101 ) ORDER BY number DESC limit 0,100

2,显示全部页数
效果 :
http://www.lightinthebox.com/producttags/B/

<% @words.total_pages.times do | page | %> 
 <a href="/search/<%= word + '/' + page.to_s %>" ><%= page %></a>
 <% end  %>

3 ,配置共用一个样式
enviroment.rb 中添加

require 'will_paginate'
WillPaginate::ViewHelpers.pagination_options[:class] = 'digg_pagination'
WillPaginate::ViewHelpers.pagination_options[:previous_label] = '<<'
WillPaginate::ViewHelpers.pagination_options[:next_label] = '>>'

4,临时指定一个样式

 <%= will_paginate @comments ,
    :class => 'apple_paginate' ,
    :previous_label => '<<上一页',
    :next_label => '下一页>>' ,
    :renderer  => 'WillPaginate::LinkRenderer'  %>

5,…

Bye Wuxi , Hello Beijing

2010.01.22 23:15 离开了无锡,来到了所谓的一线城市 北京,从实习到工作已经一年时间了,一直在无锡做ror,接触了少量的java,和公司的老板,同事相处的还算融洽,特别是和@bestwyw 玩的比较多,刚去时,教我用google , 说google多么的强大,baidu多么的ugly ,教我戴套(tor),教我twitter。。很多,最后走的那边晚上,请我吃饭了,感谢的话不多说了。。保重!
离开无锡的那些天,用手机拍了几张小区附近的照片,以示留念………

在无锡唯一花了80元门票去玩的 三国城

SAM_0161

SAM_0108

无锡蠡湖,我的同学来无锡了,我都是带他们去这里玩,1 不要钱,2离我比较近….

SDC13226

工作了1年的地方,我在的时候,这个园区貌似中科芯 和 同捷汽车设计 两家比较牛…

530p

12小时后,到了北京,北京给我的第一印象不是冷,是城市的脏,乱,差,天气不好,刚下火车,门口要查票,前面就两个窗口查票,后面人人都在往前挤,速度贼慢着,这还象个首都的办事效率 吗…
北京部分城市建筑是红墙红瓦,这个可能和北京的政治有点关系,就像第一次到苏州,发现很多建筑是白墙黑瓦,有点江南韵味….
到北京感觉不冷,但是很干燥,路边或者物体上,尘土比较多,看着一个城市象笼罩在沙尘暴中一样,不舒服….
北京的地铁 和 公交 太便宜了。。很适合我们这些外地人,或者没车族,公交4 毛,地铁 2元随便做..嘿嘿, 爽
…..
现在已经安顿下来了,公司的cto和我一个大学同学帮我一起找了房子,感谢一下,这边的cto 看着很随和,技术又牛,走sohu 过来的,膜拜一下,刚过来还没上班,在公司小玩了以下,就叫我处理一个500万条记录左右的一个文件,遍历查关键字,并且按大小排序,第一次处理这么大的数量级,有点手足无措,不过还好,遇到问题了,总监总是能够以他最快的速度,最好的方法告诉我怎么做….呵呵,很喜欢这样的工作,很喜欢这样的挑战………

既来之,则安之……好好工作,好好赚钱,好好生活~!