Ruby WEBrick アクセスログフォーマットの変更
require 'webrick'
config = {
:DocumentRoot => '.',
:AccessLog => [
[ $stderr, WEBrick::AccessLog::COMBINED_LOG_FORMAT ],
],
}
server = WEBrick::HTTPServer.new(config)
trap("INT") { server.shutdown } # Ctrl + C で shutdown
server.start
Ruby はてなブックマーク Atom API WSSE認証
はてなブックマークAtomAPI/はてなフォトライフAtomAPI で使用するWSSE認証のHTTP X-WSSEヘッダを作成するRubyスクリプト
$KCODE = 'u'
require 'time'
require 'digest/sha1'
def hatena_wsse_header(hatena_id, password)
# Nonce : HTTPリクエスト毎に生成したセキュリティ・トークン
# ランダムなバイト列 http://sheepman.parfait.ne.jp/20050104.html
nonce = Array.new(10){ rand(0x100000000) }.pack('I*')
nonce_base64 = [nonce].pack("m").chomp # Base64エンコード
# Created : Nonceが作成された日時をISO-8601表記で記述したもの
now = Time.now.utc.iso8601
# PasswordDigest : Nonce, Created, パスワードを文字列連結しSHA1アルゴリズムでダイジェスト化して生成された文字列を、Base64エンコードした文字列
digest = [Digest::SHA1.digest(nonce + now + password)].pack("m").chomp
credentials = sprintf(%Q<UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s">,
hatena_id, digest, nonce_base64, now)
{ 'X-WSSE' => credentials }
end
Ruby はてなブックマークの全ブックマークを取得するスクリプト
はてなブックマークAtomAPI FeedURIを使用して全ブックマークを取得するRubyスクリプト
require 'hatena_wsse_header' は d:id:toward:20051225:ruby_hatena_wsse
#!/usr/local/bin/ruby -w
$KCODE = 'u'
require 'net/http'
Net::HTTP.version_1_2
require 'rexml/document'
require 'pstore'
require 'hatena_wsse_header' # はてなブックマーク/はてなフォトライフ AtomAPI WSSE認証 HTTP X-WSSEヘッダを作成
hatena_id = 'hatena_id' # はてなID
password = 'password' # パスワード
bookmarks = [] # 全ブックマーク
# 全ブックマークを取得
Net::HTTP.start('b.hatena.ne.jp') do |http|
offset = 0
has_next = true
while has_next
header = { 'User-Agent' => "Ruby/#{VERSION}" }.update(hatena_wsse_header(hatena_id, password))
response = http.get('/atom/feed?of=' + offset.to_s, header)
root = REXML::Document.new(response.body).elements['feed']
total_results = root.elements['openSearch:totalResults'].text.to_i
start_index = root.elements['openSearch:startIndex'].text.to_i
items_per_page = root.elements['openSearch:itemsPerPage'].text.to_i
if total_results >= start_index + items_per_page
offset += items_per_page
else
has_next = false
end
root.elements.each('entry') do |elem|
bookmark = {}
bookmark[:title] = elem.elements['title'].text
bookmark[:url] = elem.elements['link[@rel="related"]'].attributes['href']
bookmark[:hb_url] = elem.elements['link[@rel="alternate"]'].attributes['href']
bookmark[:atom_edit] = elem.elements['link[@rel="service.edit"]'].attributes['href']
bookmark[:eid] = bookmark[:atom_edit].split('/')[-1]
bookmark[:issued] = elem.elements['issued'].text
bookmark[:summary] = elem.elements['summary'].text
bookmark[:tag] = []
elem.elements.each('dc:subject') do |tag|
bookmark[:tag] << tag.text
end
bookmarks << bookmark
end
end
end
# 全ブックマークをPStoreで保存
db = PStore.new("hatena_bookmark-#{hatena_id}.pstore")
db.transaction do
db['bookmarks'] = bookmarks
end
# PStoreファイルから全ブックマークを読み込み
bookmarks2 = nil
db2 = PStore.new("hatena_bookmark-#{hatena_id}.pstore")
db2.transaction do
bookmarks2 = db2['bookmarks']
end
require 'pp'
pp bookmarks2.collect { |i| i[:title] }ブックマークを公開しているはてなIDは、Atomフィードで同様のことが可能(WSSE認証不要)
23・24行目を変更
header = { 'User-Agent' => "Ruby/#{VERSION}" }
response = http.get("/#{hatena_id}/atomfeed?of=" + offset.to_s, header)
Ruby XMLRPC はてなブックマーク件数取得API
Ruby XMLRPC4R(標準添付ライブラリ)を使用したはてなブックマーク件数取得APIのサンプル
XMLRPC::Client#call - 例外が発生するバージョン
#!/usr/local/bin/ruby -w
require 'xmlrpc/client'
end_point = 'http://b.hatena.ne.jp/xmlrpc'
urls = [
'http://www.rubyonrails.org/',
'http://www.rubyonrails.com/',
'http://rubyonrails.org/',
'http://rubyonrails.com/']
client = XMLRPC::Client.new2(end_point)
begin
result = client.call('bookmark.getCount', *urls)
result.each do |url, count|
puts "#{url} : #{count}"
end
rescue XMLRPC::FaultException => e
puts "Error: #{e.faultCode}: #{e.faultString}"
end実行結果
http://rubyonrails.org/ : 3 http://www.rubyonrails.org/ : 87 http://rubyonrails.com/ : 1 http://www.rubyonrails.com/ : 45
XMLRPC::Client#call2 - 例外が発生しないバージョン
client = XMLRPC::Client.new2(end_point)
ok, result = client.call2('bookmark.getCount', *urls)
if ok
result.each do |url, count|
puts "#{url} : #{count}"
end
else
puts "Error: #{result.faultCode}: #{result.faultString}"
end
XMLRPC::Client#proxy - 例外が発生するバージョン
client = XMLRPC::Client.new2(end_point)
bookmark = client.proxy('bookmark')
begin
result = bookmark.getCount(*urls)
result.each do |url, count|
puts "#{url} : #{count}"
end
rescue XMLRPC::FaultException => e
puts "Error: #{e.faultCode}: #{e.faultString}"
end
XMLRPC::Client#proxy2 - 例外が発生しないバージョン
client = XMLRPC::Client.new2(end_point)
bookmark = client.proxy2('bookmark')
ok, result = bookmark.getCount(*urls)
if ok
result.each do |url, count|
puts "#{url} : #{count}"
end
else
puts "Error: #{result.faultCode}: #{result.faultString}"
end
Agile Web Development with Rails - Chapter 7
Source Code depot5〜depot7
Agile Web Development with Rails - Chapter 6
Source Code depot1〜depot4
6.1 Iteration A1: Get Something Running
Create a Rails Application
toward@localmachine ~/rails $ rails depot toward@localmachine ~/rails $ cd depot/
Configure the Application (順番入れ替え)
MySQL Administratorでデータベースdepot_developmentを作成
config/database.ymlを変更
login: &login adapter: mysql username: root password: xxxx host: LOCALHOST development: database: depot_development <<: *login test: database: depot_test <<: *login production: database: depot_production <<: *login
Create the Product Table (順番入れ替え)
Migration
toward@localmachine ~/rails/depot
$ ruby script/generate migration InitialScheme
create db/migrate
create db/migrate/001_initial_scheme.rbdb/migrate/001_initial_scheme.rb 変更
class InitialScheme < ActiveRecord::Migration
def self.up
create_table :products do |t|
t.column :title, :string, :limit => 100, :null => false
t.column :description, :text, :null => false
t.column :image_url, :string, :limit => 200, :null => false
t.column :price, :float, :null => false
end
end
def self.down
drop_table :products
end
endtoward@localmachine ~/rails/depot $ rake --trace migrate (in /home/toward/rails/depot) ** Invoke migrate (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute migrate
Create the Maintenance Application
toward@localmachine ~/rails/depot
$ ruby script/generate scaffold Product Admin
exists app/controllers/
exists app/helpers/
create app/views/admin
exists test/functional/
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
create app/models/product.rb
create test/unit/product_test.rb
create test/fixtures/products.yml
create app/views/admin/_form.rhtml
create app/views/admin/list.rhtml
create app/views/admin/show.rhtml
create app/views/admin/new.rhtml
create app/views/admin/edit.rhtml
create app/controllers/admin_controller.rb
create test/functional/admin_controller_test.rb
create app/helpers/admin_helper.rb
create app/views/layouts/admin.rhtml
create public/stylesheets/scaffold.css
toward@localmachine ~/rails/depot
$ ruby script/server
=> Booting WEBrick...
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2005-12-18 00:16:45] INFO WEBrick 1.3.1
[2005-12-18 00:16:45] INFO ruby 1.8.3 (2005-09-21) [i386-cygwin]
[2005-12-18 00:16:45] INFO WEBrick::HTTPServer#start: pid=4008 port=3000
6.2 Iteration A2: Add a Missing Column
toward@localmachine ~/rails/depot
$ ruby script/generate migration AddProductDateAvailable
exists db/migrate
create db/migrate/002_add_product_date_available.rbdb/migrate/002_add_product_date_available.rb 変更
class AddProductDateAvailable < ActiveRecord::Migration
def self.up
add_column :products, :date_available, :datetime, :null => false
end
def self.down
remove_column :products, :date_available
end
endtoward@localmachine ~/rails/depot $ rake --trace migrate (in /home/toward/rails/depot) ** Invoke migrate (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute migrate
toward@localmachine ~/rails/depot
$ ruby script/generate scaffold Product Admin
exists app/controllers/
exists app/helpers/
exists app/views/admin
exists test/functional/
dependency model
exists app/models/
exists test/unit/
exists test/fixtures/
identical app/models/product.rb
identical test/unit/product_test.rb
identical test/fixtures/products.yml
overwrite app/views/admin/_form.rhtml? [Ynaq] a
forcing scaffold
force app/views/admin/_form.rhtml
identical app/views/admin/list.rhtml
identical app/views/admin/show.rhtml
identical app/views/admin/new.rhtml
identical app/views/admin/edit.rhtml
identical app/controllers/admin_controller.rb
identical test/functional/admin_controller_test.rb
identical app/helpers/admin_helper.rb
identical app/views/layouts/admin.rhtml
identical public/stylesheets/scaffold.css
