Wednesday, September 30, 2009

BarBar Sati

昨日さちに髪の毛を切ってもらった
所要時間40分
細かいところで手を抜かないのがすごいな
100円ショップで買ったまことちゃんカラーの敷物は
髪の毛が張り付かないので使えている

Ruby flickrup.rb

食事の写真をFlickrにアップするのが大変なので
exifの情報に基づいてタイトルを生成し
FlickrにアップするRubyのクラスFlickrPhotoを書いた
使い方は以下のようにする

まずアップするための認証がいるので
API_KEY = '****'
SECRET = '***'
token = 'flickr.dat'

FlickrPhoto.new(token, API_KEY, SECRET)
API_KEYとSECRETはflickr/base.rbにセットすればここでは省略できる

次いでアップロード
photo = FlickrPhoto.new(ARGV)
photo.title = "Tokyo tower on #{photo.mon} #{photo.day} #{photo.year(:short)}"
photo.tags = ['tokyo', 'travel']
photo.only_friend

photo.upload

これで写真のアップが楽になる

Friday, September 25, 2009

DataMapper filter

one to manyのフィルタは
Post.all('user.name' => 'merborne')
のように簡単に行くけど
many to manyの場合はちょっと面倒
Post.all(:conditions => {:id => PostTag.all(:tag_id => 3).map { |pt| pt.post_id }})
つまりRelationTableを使ってやる必要がある

Thursday, September 17, 2009

Git command

設定
> git config --global --list #listing config
> git config --global user.name "melborne"
> git config --global user.email "p@gmail.com"
> git config --global color.ui "auto"

状態を見る
> git status
> git diff # see only not staged changes
> git diff --cached # see only staged changes
> git diff HEAD # see all changes
> git log -1 #check last log

ファイルの追加・変更
> git add myfile.rb # change staging area
> git add -i # interactive mode
> git commit -m 'initial commit' # apply stage data to repo
> git mv a.txt b.txt #only required is commit
gitignore or git/info/exludeファイルに追跡しないファイルを追加(*.dbとか)
> git commit -C HEAD -a --amend #amend most recent commit with same comment
> git revert #revert a commit
> git revert -n HEAD # only revert head without commit
> git checkout #discard changes in working dir

ブランチ
> git branch RB_1.0 master # create RB_1.0 branch for release
> git checkout RB_1.0 # change working branch to RB_1.0
> git tag 1.0 RB_1.0 # tagged 1.0 to RB_1.0's current status
> git checkout master
> git rebase RB_1.0 # rebase master with RB_1.0
> git branch -d RB_1.0 # delete RB_1.0 branch
> git branch -m oldname newname # rename branch
> git branch RB_1.0.1 1.0 # create branch RB_1.0.1 for tag 1.0
> git archive --format=tar --prefix=mysite-1.0/ 1.0 | gzip > mysite-1.0.tar.gz

マージ
>git merge RB_1.0 # merge RB_1.0 to master(when cuurent branch is master)
競合が生じた場合はソース上に表示される
修正して解消したのちcommitする必要がある
> git cherry-pick 321d.. #merge only 321d.. commit to master
> git mergetool #use when merge conflict

プル
> git pull #fetch repo and merge
> git pull origin RB_0.1 #merge RB_0.1 branch
> git fetch #only fetch
> git remote add # alias name
> git remote #list aliases
> git remote show #show info of alias

> cd /work
> git clone git://github.com/....

Wednesday, September 16, 2009

Tile: Bookmarklet with AJAX

hatena bookmarkletを参考にして
対象サイトにフォームをアペンドしてブックマークする方法を模索
いい線まで行ってると思うけどポストがうまくいかない
404がでる
bookmarklet
%a#booklet{:href=>"javascript:(function(){var%20d=(new%20Date);var%20s=document.createElement('script');s.charset='UTF-8';s.src='http://192.168.1.3:4567/javascripts/let.js';(document.getElementsByTagName('head')[0]||document.body).appendChild(s);})();"} Brick+

let.js
$(document).ready(function(){
$('body').append("<form id='bookmark-form' action='/' method='post' style='position: absolute; top: 10px; right: 10px;z-index: 10002';><textarea name='body' rows='6' cols='25'></textarea></br><input type='submit' value='New'><p id='ip'>POST!</p></form>");
$('#ip').click(function(){
$.post('http://192.168.1.3:4567/', $('textarea:name').text(), function(){
alert('posted!');
});
});
});

Tuesday, September 08, 2009

ruby mapreduce

module Enumerable
def mapreduce(init=0, blk)
self.map { |elm| blk[elm] }.inject(init) { |mem, var| yield(mem, var) }
end
end

a = [17, 14, 21, 21, 24]
b = a.map { |elm| elm**2 } # =>
b.inject { |mem, elm| mem + elm } # =>

p a.mapreduce(0, lambda { |elm| elm**2 }) { |mem, elm| mem + elm } # =>

p a.mapreduce("", lambda { |elm| elm.to_s(36) }){ |mem, elm| mem << elm } # =>

意味なさそう

Monday, September 07, 2009

ruby mapreduce

Google MapReduce

# docID, value  => wordID, docID:docPos
WDIC = {101 => 'Page', 102 => 'of', 103 => 'School', 104 => 'Sakura', 105 => 'Kaede'}.invert

web = {1 => "Page of Sakura School", 2 => "Page of Kaede School"}

mapped = web.map do |doc_id, content|
  content.scan(/\w+/).map.with_index { |word, i| [WDIC[word], [doc_id, i]] }
end.flatten(1)

p mapped.inject(Hash.new([])) { |h, (word_id, v)| h[word_id] += [v]; h }

# => {101=>[[1, 0], [2, 0]], 102=>[[1, 1], [2, 1]], 104=>[[1, 2]], 103=>[[1, 3], [2, 3]], 105=>[[2, 2]]}

Sunday, September 06, 2009

Ruby UDP Broadcast

require "socket"
require "timeout"

port = ARGV[1] || 'echo'
sock = UDPSocket.open

sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)

begin
  sock.send('message', 0, '<broadcast>', port)
  timeout(5) {
    loop do
      msg, addr = sock.recvfrom(20)
      p addr
    end
  }
rescue TiemoutError
  
end
sock.close

Ruby UDP sample

echo_srv.rb
require "socket"

port = ARGV[1] || 'echo'
sock = UDPSocket.open
sock.bind('', port)

loop do
msg, (afam, port, host, ip) = sock.recvfrom(1024)
sock.send(msg, 0, ip, port)
end

Server側はClient毎にスレッド化する必要がない
recvfromしたデータにはClientのアドレス情報が入ってる
エコーバックするときにそのアドレス情報を指定する

echo_cln.rb
require "socket"

host = ARGV[0] || 'localhost'
port = ARGV[1] || 'echo'

sock = UDPSocket.open

while msg = STDIN.gets
sock.send(msg, 0, host, port)
print sock.recvfrom(1024)[0]
end
sock.close

Client側はsendするとき自アドレスを一緒に送る