Posts Tagged ‘Ruby’

| No Comments | 8月 26th, 2011

 Ruby1.8 は、tmail で -> Rubyで受信メール解析(変なヤバいもんログ内) どうぞ。

 gem で mail をインストールします。

# gem install mail

メールのファイルを解析する方法です。

require 'mail'
mail = Mail.read("mail_dir/001.eml")
mail.from.first # 送信元 mail.from に配列で入ってる
mail.to         # 送信先 mail.to に配列で入ってる
mail.subject    # 件名
mail.body       # 本文

みたいな感じに取得できます。

, | No Comments | 8月 11th, 2011

Rails の unit test を書いていて、関連がないテーブルの primary key が知りたい状況があった。

関連があるテーブルだと、

class User < ActiveRecord::Base
has_many :posts
end
class Post < ActiveRecord::Base
belongs_to :user
end

みたいなときに

test/fixtures/users.yml

chihaya:
name: 千早

test/fixtures/posts.yml

first:
user: chihaya
title: くっ…!
body: 先日フェスがあったのですが…

みたいな感じにすると関連が作れる。

今回は、単純なログみたいなもので、色んなテーブルの id を、target_id みたいなところにしまって、クラス名と合わせてユニークになるように管理してた。数が多かったのと関連付けて取る必要が無かったので、関連を作ってなかったんだけれども、fixture を書く時に、外部の id の取得方法に迷った。

つまり、先ほどの例で、has_many, belongs_to が無かった時にどうするかということです。
users.yml に、 id:1 とか書くというのも1つの方法です。

id を指定せずに rake fixtures:load ってすると、id が結構大きな数字になりますが、あれはラベルの文字列によって計算された値みたいですね。

ActiveRecord::Fixtures.identify(label) というメソッドで計算されていて、プラットフォーム依存で、同じ文字列を与えれば同じ値が返ってくる仕組みになっているようです。

そうすると、先ほどの例だと

test/fixtures/posts.yml

first:
user_id: <%= ActiveRecord::Fixtures.identify(:chihaya) %>
title: くっ…!
body: 先日フェスがあったのですが…

とすると、常に千早の id が取れるようになります。ActiveRecord::Fixtures.identify(:chihaya) の値は、見て分かるようにテーブルに依存することはなく、別テーブルで chihaya というラベルを使うと、同じ id になります。ActiveRecord::Fixtures が見つからないときは、 require ‘active_record/fixtures’ とします。

なんだろうなーと思ってた巨大な整数の id の計算方法がわかってすっきりしました。

, , , | No Comments | 6月 17th, 2010

 WebSocketを使って、@projecthl2先生といっしょにリアルタイム連動お絵かきチャットを作ってみました。

おえかきちゃっと♥

 WebSocket 速いです!リアルタイムで同期しているので、数人でやると、毎秒サーバと50回とかやりとりしてるのだけど (1回の通信はおそらく100bytesくらい)、サーバ側はほとんどCPU食ってないみたいですね。すごぃ。もし AJAX とか使うとすると、毎秒50回とかサーバにリクエスト飛ばそうとか絶対考えないよ。2窓開いてみると、遅延はほぼ0で通信できてることが分かります。

 WebSocket は、やってみたところでは文字列しか送れなさそうなので、今までAJAXでJSON扱ってたようなものは文字列にして送る必要がありました。

JSON.stringfy({x:100, y:100})

みたいにしてサーバに送って、サーバからJSONを文字列にしたものを送って

JSON.parse(event.data)

的な感じにJSONを得てみました。

 お絵かき部分と、チャット部分でWebSocketを使っています。サーバ側のWebSocket部分は em-websocket を使いました。EventMachine を使った WebSocket 実装みたいです。WebSocket はシンプルでした。EventMachine の使い方を調べるのに時間がかかった。。

 お絵かき部分は、canvas を使っています。ファイルをロードの部分は XMLHttpRequest Level2 を使っています。最初は、FileAPI を使って実装すればサーバ経由せずにファイルロードできてウマー!! と思ったけど、まだ Firefox でしか使えないみたいなので、あきらめました。Twitterに投稿っていう部分は、canvas から toDataURL() で canvas に描かれたデータが Base64エンコードされたものを取って、そいつをサーバ側に送って保存しています。今までの XMLHttpRequest ってファイルをサーバに送信出来なかったので、無理矢理 iframe 使ったりとか頑張っていたけど、ファイルが送れるようになってすごい便利そうです。使い方は今までのものと大して変わらないみたいですし。

 
 HTMLを生成する部分は sinatra ちゃんです。sinatra ちゃん可愛いよ。センスいいと思う。

 2日で作られたものなので、例外処理とかあんまりしてなぃ。。でも2日でこのくらいのもの出来るとは、高機能なHTMLですねー

 ソースコードを github で公開しています。 -> ecpplus / websocket_chat

| No Comments | 11月 12th, 2009

 amazon web services が署名が必要になって、名前も amazon Product Advertising API とかなってたので、コードを変更しなきゃと思ってサンプルページ見たけど、途中に描かれている値が間違っているみたいだ…。

サンプルリクエストに署名を行うためのステップ 【amazonヘルプ】 の、Version=2009-03-31 という文字列が、正しくは Version=2009-01-06 みたいです。

下記のサイトを参考にしました。下記のページだと、ヘルプページと最終出力は同じなのに、入力値が違う!って気づいたので、合わせてみたらちゃんと出来ました。

require 'hmac/sha2'
require 'base64'
 
def genreate_hash(original_url)
  url_string = original_url.split('&').sort.join('&')
  string = ['GET', 'webservices.amazon.com', '/onca/xml', url_string].join("\n")
  Base64.encode64(HMAC::SHA256.digest('1234567890', string))
end

上記で original_url を

"Service=AWSECommerceService&AWSAccessKeyId=00000000000000000000&Operation=ItemLookup&ItemId=0679722769&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReviews&Version=2009-01-06&Timestamp=2009-01-01T12%3A00%3A00Z"

とすれば、

Nace+U3Az4OhN7tISqgs1vdLBHBEijWcBeCqL5xN9xg=\n

が出力されます。

なお、サンプル通りの文字列でやると、url_string が

"Service=AWSECommerceService&AWSAccessKeyId=00000000000000000000&Operation=ItemLookup&ItemId=0679722769&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReviews&Version=2009-03-31&Timestamp=2009-01-01T12%3A00%3A00Z"

となって、

EDWJ1+VXQhAtPDKQ0f+wpaFQcBVDJyTIpDP7BZgxMiA=\n

が出力されます。

| No Comments | 7月 26th, 2009

Windows の Ruby で、Thread 内で新規プロセスを立ち上げようとすると、Thread 内で全体の動作を止めてしまうらしい。たとえば、

Thread.new do 
  `something.exe`
end

とやってみると、`something.exe` の処理が終わるのを待っているようだ。

Windows+Rubyで外部プロセスを立ち上げる時の注意 にまさにその情報が載っていた。Windows は、Windows::Process 等を使う必要があるみたいです。

require 'rubygems'
require 'win32/process'
require 'windows/synchronize'
require 'windows/process'
require 'windows/handle'
 
include Windows::Synchronize
include Windows::Process
include Windows::Handle
 
t = Thread.new do 
  Process.create('app_name' => 'something.exe')
end
puts "hello!"
t.join

のようにしたら、プロセス生成してもそこで止まることは無くなりました。

download the hurt locker