2011
09/28
RMagick のインストールでコケる問題
昨日から、自分の Lion 環境上で rmagick を使う Rails プロダクトの Bundle install 時に、
/Users/xxx/.rvm/rubies/ruby-1.9.2-p290/bin/ruby extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for /usr/bin/gcc-4.2... yes
checking for Magick-config... yes
checking for ImageMagick version >= 6.4.9... yes
checking for HDRI disabled version of ImageMagick... yes
checking for stdint.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.
Provided configuration options:
--with-opt-dir
--without-opt-dir
--with-opt-include
--without-opt-include=${opt-dir}/include
--with-opt-lib
--without-opt-lib=${opt-dir}/lib
--with-make-prog
--without-make-prog
--srcdir=.
--curdir
--ruby=/Users/xxx/.rvm/rubies/ruby-1.9.2-p290/bin/ruby
/Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:368:in `try_do': The complier failed to generate an executable file. (RuntimeError)
You have to install development tools first.
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:452:in `try_cpp'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:834:in `block in have_header'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:693:in `block in checking_for'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:280:in `block (2 levels) in postpone'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:254:in `open'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:280:in `block in postpone'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:254:in `open'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:276:in `postpone'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:692:in `checking_for'
from /Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/mkmf.rb:833:in `have_header'
from extconf.rb:193:in `<main>'
というエラーで rmagick のインストールに失敗するという現象に悩まされていたのですが、
単純にググってもそれらしい情報に行き当たらず、苦労していたので原因と解決方法をメモしておきます。
まず、この環境ですが、ImageMagick を brew で入れた時から怪しいところがありました。
% brew install imagemagick ==> Downloading http://downloads.sf.net/project/machomebrew/Bottles/imagemagick-6.7.1-1-bottle.tar.gz File already downloaded in /Users/xxx/Library/Caches/Homebrew ==> Pouring imagemagick-6.7.1-1.bottle.tar.gz ==> Caveats Some tools will complain unless the ghostscript fonts are installed to: /usr/local/share/ghostscript/fonts ln: Wand.pc: Permission denied Error: The linking step did not complete successfully The formula built, but is not symlinked into /usr/local You can try again using `brew link imagemagick' ==> Summary /usr/local/Cellar/imagemagick/6.7.1-1: 1389 files, 32M
良く見ると、途中でエラーを吐いています。シンボリックリンクが作れなかったから、手動で brew link しろと。
単純に実行しただけだと ” ln: Wand.pc: Permission denied ” を解決できず同じ様に死んでしまうものの、 sudo で実行すると完了し、一見問題ないように見えます。
しかし、肝心の rmagick のインストール時には上記のようなエラーになってしまいました。
bundle が悪いのかと思って、単純に
% gem install rmagick
しても、同じでした。冒頭のエラーを良く見ると
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers. Check the mkmf.log file for more
details. You may need configuration options.
とあるので、mkmf.log を読んでみる事に。
% less ~/.rvm/gems/ruby-1.9.2-p290/gems/rmagick-2.13.1/ext/RMagick/mkmf.log
checking for Ruby version >= 1.8.5... -------------------- yes
--------------------
find_executable: checking for /usr/bin/gcc-4.2... -------------------- yes
--------------------
find_executable: checking for Magick-config... -------------------- yes
--------------------
checking for ImageMagick version >= 6.4.9... -------------------- yes
--------------------
checking for HDRI disabled version of ImageMagick... -------------------- yes
--------------------
"/usr/bin/gcc-4.2 -o conftest -I/Users/xxx/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/x86_64-darwin11.0.1 -I/Users/xxx/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/ruby/backward -I/Users/xxx/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1 -I. -I/usr/local/Cellar/imagemagick/6.7.1-1/include/ImageMagick -I/usr/local/Cellar/imagemagick/6.7.1-1/include/ImageMagick -fopenmp conftest.c -L. -L/Users/xxx/.rvm/rubies/ruby-1.9.2-p290/lib -L/usr/local/Cellar/imagemagick/6.7.1-1/lib -L/usr/X11/lib -L/usr/local/Cellar/imagemagick/6.7.1-1/lib -lMagickCore -llcms -ltiff -lfreetype -ljpeg -L/usr/X11/lib -lfontconfig -lXext -lSM -lICE -lX11 -lXt -lbz2 -lz -lm -lgomp -lpthread -lltdl -lruby.1.9.1-static -lpthread -ldl -lobjc "
ld: library not found for -llcms
collect2: ld returned 1 exit status
checked program was:
/* begin */
1: #include "ruby.h"
2:
3: int main() {return 0;}
/* end */
-llcms を見つけられないのが原因だったようです。
liblcms とはなんぞ、と思ってググったらこのページに引っ掛かりました。Libraries for the Little CMS Engine というものらしいので、 再度この名前でググると、どうやらカラーマネジメントシステムのライブラリみたい。
しかし、必要なら brew が依存性解決に入れてくれているだろうと見てみると
$ brew list cmake imagemagick jpeg little-cms mysql nkf readline zsh gdbm jasper libtiff mongodb netcat pidof wget
案の定、little-cms というソレらしいのが居ます。
が、ここで先程、brew で ImageMagick 入れようとしたときにエラーが出ていたのを思い出しました。
依存性解決のために自動で入れる途中で、同じようなエラーに遭遇して、little-cms パッケージが正常にインストールされていないのではないかという仮説を思いつき、この腐った brew 環境を叩き直すために、お医者様の力を借りる事にします。
% brew doctor
Unbrewed dylibs were found in /usr/local/lib.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected dylibs:
/usr/local/lib/libmacfuse_i32.2.dylib
/usr/local/lib/libmacfuse_i64.2.dylib
/usr/local/lib/libosxfuse_i32.2.dylib
/usr/local/lib/libosxfuse_i64.2.dylib
Unbrewed .pc files were found in /usr/local/lib/pkgconfig.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected .pc files:
/usr/local/lib/pkgconfig/osxfuse.pc
Unbrewed .la files were found in /usr/local/lib.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.
Unexpected .la files:
/usr/local/lib/libosxfuse_i32.la
/usr/local/lib/libosxfuse_i64.la
/usr/local/lib/pkgconfig isn't writable.
This can happen if you "sudo make install" software that isn't managed
by Homebrew.
If a brew tries to write a .pc file to this folder, the install will\nfail during the link step.
You should probably `chown` /usr/local/lib/pkgconfig
Some "config" scripts were found in your path, but not in system or Homebrew folders.
`./configure` scripts often look for *-config scripts to determine if software packages
are installed, and what additional flags to use when compiling and linking.
Having additional scripts in your path can confuse software installed via Homebrew if
the config script overrides a system or Homebrew provided script of the same name.
/usr/X11R6/bin
freetype-config libpng-config libpng15-config
brew doctor は概ね、勝手に /usr/local 以下に入ったosxfuseがお気に召さないようですが、
/usr/local/lib/pkgconfig isn’t writable.
This can happen if you “sudo make install” software that isn’t managed
by Homebrew.If a brew tries to write a .pc file to this folder, the install will\nfail during the link step.
You should probably `chown` /usr/local/lib/pkgconfig
大事なのはおそらくここでしょう。
見ると osxfuse インストール時に作られたたらしいこのディレクトリは
drwxr-xr-x 4 root wheel 136 9 27 22:02 pkgconfig
と、root 権限で置かれていました。これを自分に chown し、
% brew uninstall little-cms % brew install little-cms
としたら、案の定、/usr/local/lib/pkgconfig 内に、先程までは存在しなかった、lcms.pc というファイルが作られました。little-cms の環境がやはり不完全だったようです。
この状態で、ImageMagick も再インストールすると
% brew uninstall imagemagick % brew install imagemagick
bundle install で RMagick のインストール時に失敗する事は無くなりました。
環境系のトラブルは面倒ですね。
2011
05/24
Redis 使ってみました。
会社に転がってた、↓ の本をつらつらと眺めていて
今まで、よくわかっていなかった NoSQL という物に興味が湧いてきました。
上記の本は、そろそろ出揃った感のある NoSQL 系のデータストアエンジンを一通り並列に紹介してくれる本で、見て、軽くわかった気になるには最適です。
ただ、結局のところ、いつも使っている SQL と何が違うのかまでは読んだだけでは充分に理解できないよね、やっぱり試してみなくちゃね、という事で、使ってみました。
NoSQL と言えども、データストア!データを保存しなくては。入れるデータの元ネタに困りましたが、困った時は他人のふんどしを借りようと Twitter から適宜引っ張ってくる事にしました。キャズムを越えたらしいという噂の Twitter から URL を含んだツイートを引っ張りだして集計したら、世間で話題になっているネタが拾えそうかなと。誰かが勝手にデータをたれ流してくれるのは収集に持ってこいですし。この辺を思い付きだけでやってしまったのが後で祟る事になるのですが、そこは後述。
保存用のスクリプトは Ruby で書く事にしたので、Redis へのアクセスに redis の gem 、また、Twitter からデータを取ってくるのにTwitter の gem を使います。
Twitter はクライアントなどが自動的に URL を短縮した状態で投稿する事が多いので、それを元 URL に戻す処理も入れる事にしました。
#!/usr/bin/ruby
require "rubygems"
require "redis"
require 'twitter'
require 'uri'
require 'net/http'
$lang = "ja"
# 短縮 URL を元に戻すための処理
def extract_url(url)
begin
uri = URI.parse(url)
# 引数で与えられた URL に対して HEAD メソッドを実行
Net::HTTP.start(uri.host, uri.port) do |http|
response = http.head(uri.path, 'User-Agent' => "Redirect Tracker")
# 実URLだと判断する条件は、以下のいずれかに合致する事
# ・レスポンスコードが200
# ・レスポンスヘッダにLocationが含まれない
# ・レスポンスヘッダLocationが、元URLと同一
if (response.code == "200") or (response['Location'] == nil) or (url == response['Location']) then
return url
else
moved_to = response['Location'].match(/^https?:\/\//) ? response['Location'] : "#{uri.host}/#{response['Location']}"
# 二重に短縮されている場合などのために再帰処理
extract_url(moved_to)
end
end
rescue => e
puts " === ERROR ( #{url} ) ==== "
puts e
end
end
begin
# ローカルホストの Redis に接続
redis = Redis.new(:host => "localhost")
# 前回取得時の最終 Tweet ID を拾う
last_id = redis.get "meta:last_id:#{$lang}"
result = nil
# 前回取得した以降の、日本語のツイートの中から、http という文字列で検索
Twitter::Search.new.containing("http").since_id(last_id).lang($lang).per_page(100).filter.reverse_each do |result|
# URL らしき文字列の切り出し
result.text.scan(/https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:@&=+$,%#]+/).each do |url|
# 短縮URL を元に戻す
exturl = extract_url(url)
if (exturl != nil) then
uri = URI.parse(exturl)
else
next
end
# 集計系は incr メソッドでアトミックに処理
id = redis.incr "data:count:whole"
host_count = redis.incr "data:count:#{uri.host}"
url_count = redis.incr "data:count:#{uri.host}:#{uri.path}"
# URL情報をリスト型で記録
redis.lpush "list:whole", exturl
redis.lpush "list:#{$lang}", exturl
redis.lpush "list:hosts", uri.host
# 念のため、ツイート情報も取っておく / Marshal.dump でオブジェクトを serialize する
redis.set "data:tweet:#{id}", Marshal.dump(result)
end
end
rescue => e
puts e
ensure
# 最後に処理した Tweet ID を記録しておく
redis.set "meta:last_id:#{$lang}", result.id
end
上記スクリプトを、cron で定期実行して、情報を収集しておきます。
読み返してみたら、検索結果を Reverse_each した上でリストに lpush してるけど、素直に each & rpush したらよかったんじゃないだろうか…。
表示系は Sinatra で間に合わせ。
require 'rubygems'
require 'sinatra'
require 'redis'
require 'uri'
set :haml, {:format => :html5}
before do
@redis = Redis.new(:host => "localhost")
end
get %r{/([0-9]+|all)?} do
# 全データ件数を取得
@total_count = @redis.get "data:count:whole"
@datas = []
# リスト長を取得(アレ?上の全データ件数と同一では?)
length = @redis.llen "list:whole"
# データ表示件数を取得。デフォルトは 100 件で、指定があれば、その件数。all なら全件
limit = 100
if params[:captures] != nil then
if params[:captures].first == "all" then
limit = length
else
limit = params[:captures].first.to_i
end
end
# downto に渡す都合で加工。リスト長が指定件数に満たない場合はリスト長を限界にする
limit = length - (length < limit ? length - 1 : limit - 1)
# 表示用データを配列に突っ込む
length.downto(limit) do |i|
url = @redis.lindex("list:whole", length - i)
begin
uri = URI.parse(url)
count = @redis.get "data:count:#{uri.host}:#{uri.path}"
rescue
count = 0
end
@datas << { :url => url, :count => count }
end
haml :index
end
__END__
@@ layout
%html
%head
%title twitter url counter
%body
= yield
@@ index
%h1 twitter url counter
%a{:href => "/hosts"} host oriented
%div
There are #{@total_count} datas here.
%div
- @datas.each do |item|
%div
#{item[:count]} :
%a{:href => "#{item[:url]}"} #{item[:url]}
所定の件数を Redis から取得して表示するだけです。
しかし、KVS ほぼ初体験な自分には「ほぼハッシュだからそのつもりで使えよ」という概念がどうも理解されていなかったようです。こんなランキング系のコンテンツなのにソートの機能を持たない list 型に突っ込んでいるのが致命的。ダラダラ出すのには使えますが、それ以外の表示方法の可能性がほぼスポイルされてしまいました。
上記の本の中にあったベンチマークのデータでは、”スピードの向こう側”に突き抜けそうなブッチ切りの爆速を示していた、Redis の速度も、集計時に、URL のリダイレクトを辿るケースが頻発する今回のプログラムではネットワークの遅延が問題になってしまって、あまり恩恵受けれず…。結局何のための Redis なのか、というところが全く見えませんでした。使ってみた、というのが唯一の成果。ちゃんとアドバンテージとディスアドバンテージを見極めた上で新技術を導入しましょうね!というお話でした。
次回は今回の反省を活かして、データストアを MongoDB とかにしてみる予定!!
参考文献
2010
07/27
Hoppy を使ってみる
自分、このブログ作らせた言い出しっぺなのに記事全然書けてませんね。
文章書くの好きだけども、苦手だからか。
ずっと書かないのもなんなので、仕事で触れたネタは極力書くようにします。
今、Flash を使ってリアルタイム Web するお仕事をしてます。Flash は余り詳しくないのですが、XMLSocket という機能を使って サーバと通信する事で、それを実現出来るらしいですね。
結構昔からある技術らしくてサーバとしてのソリューションはそれなりの数が出ているらしいけれども、何がいいかはよくわからない、というところで Hoppy を使ってみる事にしました。選んだ理由は、Perl で書かれていたから。とは言え、いわゆるモダン Perl という奴も実は余り詳しくなかったりします。Perl の知識は10年以上前に CGI とか書いてた頃のままなので。とはいえ、Java とかで書かれてる他のソリューションよりは扱い易いかな、という気がしたんです。Java も不案内なので。そうするとお前何が出来るんだよ、とかいう話になりそうですが、そんな事考えると眠くなるので、弄ってみる事にします。
で、使おうと決めたらまずは資料探しなのですが、残念な事に余りヒットしない。
このくらい?
仕方ないので体当たりで使ってみる事にしました。しかし、恐しい事に「POEって何?」というところから始まる手探り感です。まずは Hoppy.pm を眺めてみます。
Hoppy クラスを new した時に _setup メソッドが呼ばれて POE の本体部分が初期化されるのだな。
POE::Component::Server::TCP->new(
Alias => $self->config->{alias} || 'xmlsocketd',
Port => $self->config->{port} || 10000,
ClientConnected => sub { $self->_tcp_handle( Connected => @_ ) },
ClientInput => sub { $self->_tcp_handle( Input => @_ ) },
ClientDisconnected => sub { $self->_tcp_handle( Disconnected => @_ ) },
ClientError => sub { $self->_tcp_handle( Error => @_ ) },
ClientFilter => $filter,
InlineStates => {
Send => sub {
$self->_tcp_handle( Send => @_ );
},
},
);
POE::Kernel->sig( INT => sub { POE::Kernel->stop } );
その前に、_load_classes メソッドで諸々の、部品として使われそうな各クラスを読み込んでいる。これは、プラガブルにするための工夫だよね。
で、そうして作った POE を start メソッドで走らせ始める、とそういう流れらしい。その程度のホントに漠然とした理解ですけど、実際に使ってみようと書いたコードが以下
test.pl
#!/usr/bin/perl
BEGIN {
unshift(@INC, '.');
}
use Hoppy;
use Data::Dumper;
my $config = {
alias => 'hoppy',
port => 12345,
test => 2,
};
my $server = Hoppy->new(config => $config );
$server->regist_service(
broadcast => 'MyService::Broadcast',
unicast => 'MyService::Unicast',
multicast => 'MyService::Multicast',
);
$server->regist_hook(
client_input => 'MyHook::ClientInput',
);
$server->start;
基本的には、作者様のスライドで示されたサンプルの猿真似。
最初に @INC を弄っているのは、同一パスにある Hoppy を CPAN で入れた物より優先ささせるため。その下で読み込んでる Data::Dumper と組み合わせて、本体のあちこちに中身どうなってるのか変数をダンプしてまわる行を足してみたかったのでこういう事をしてます。
Hoppy.pm 内には、broadcast, multicast, unicast の3つのメソッドがあったのでそれらを全て試してみることに。また、Hook の仕組みも試してみたかったので、クライアントからの入力をフックして処理を走らせるようにもしてみました。
MyService/Broadcast.pm
package MyService::Broadcast;
use base qw(Hoppy::Service::Base);
use Data::Dumper;
sub work {
my $self = shift;
my $args = shift;
my $c = $self->context;
my $in_data = $args->{in_data};
my $poe = $args->{poe};
my $session_id = $poe->session->ID;
print "now broadcastting\n";
$c->broadcast({
sender => $session_id,
message => $in_data->{params}->{message},
});
print "broadcasting done\n";
}
1;
MyService/Multicast.pm
package MyService::Multicast;
use base qw(Hoppy::Service::Base);
use Data::Dumper;
sub work {
my $self = shift;
my $args = shift;
my $c = $self->context;
my $in_data = $args->{in_data};
my $poe = $args->{poe};
my $session_id = $poe->session->ID;
my $user_id = $in_data->{params}->{user_id};
print "now multicastting\n";
$c->multicast({
sender => $session_id,
room_id => $c->{room}->{where_in}->{$user_id},
message => $in_data->{params}->{message},
});
print "multicasting done\n";
}
1;
MyService/Unicast.pm
package MyService::Unicast;
use base qw(Hoppy::Service::Base);
use Data::Dumper;
sub work {
my $self = shift;
my $args = shift;
my $c = $self->context;
my $in_data = $args->{in_data};
my $poe = $args->{poe};
my $session_id = $poe->session->ID;
my $user_id = $in_data->{params}->{user_id};
print "now unicastting\n";
$c->unicast({
sender => $session_id,
user_id => $in_data->{params}->{target_id},
message => $in_data->{params}->{message},
});
print "unicasting done\n";
}
1;
MyHook/ClientInput.pm
package MyHook::ClientInput;
use Data::Dumper;
use base qw(Hoppy::Hook::Base);
sub work {
my $self = shift;
my $args = shift;
my $c = $self->context;
print Dumper($c);
}
1;
これで、チャットサーバ的な物が出来ました。
test.pl を実行しておいて、telnet から接続し、以下のような入力を順に送るとメッセージが送れたりします。(送った本人には届かないので、テストの為には二カ所以上から telnet する必要があります)
{"method":"login","params":{"user_id":"test","room_id":"testing_room"}}
{"method":"broadcast","params":{"user_id":"test","message":"broadtestes"}}
{"method":"multicast","params":{"user_id":"test","message":"multitestes"}}
{"method":"unicast","params":{"user_id":"test","target_id":"test2","message":"unitestes"}}
Perl よくわからないながらも、とりあえず動くようになったので、もう少しいじり回してみようと思います
2010
03/12
Ethna でフォーム定義の値を取ってくる
Ethna で下記のようなフォーム定義を使えば
'pref' => array(
'type' => VAR_TYPE_INT,
'form_type' => FORM_TYPE_SELECT,
'name' => '出身地',
'required' => 'true',
'option' => array(
'01' => '北海道', '02' => '青森県', '03' => '岩手県', '04' => '宮城県', '05' => '秋田県',
'06' => '山形県', '07' => '福島県', '08' => '茨城県', '09' => '栃木県', '10' => '群馬県',
'11' => '埼玉県', '12' => '千葉県', '13' => '東京都', '14' => '神奈川県', '15' => '新潟県',
'16' => '富山県', '17' => '石川県', '18' => '福井県', '19' => '山梨県', '20' => '長野県',
'21' => '岐阜県', '22' => '静岡県', '23' => '愛知県', '24' => '三重県', '25' => '滋賀県',
'26' => '京都府', '27' => '大阪府', '28' => '兵庫県', '29' => '奈良県', '30' => '和歌山県',
'31' => '鳥取県', '32' => '島根県', '33' => '岡山県', '34' => '広島県', '35' => '山口県',
'36' => '徳島県', '37' => '香川県', '38' => '愛媛県', '39' => '高知県', '40' => '福岡県',
'41' => '佐賀県', '42' => '長崎県', '43' => '熊本県', '44' => '大分県', '45' => '宮崎県',
'46' => '鹿児島県', '47' => '沖縄県',
),
)
テンプレートではフォームヘルパを利用して
{form_input name=”pref”}
と書くだけで都道府県を選択する確認ダイアログが作れる。
ただ、この次の確認画面で
{$form.pref}
とだけ書いた場合に、意味の無い値が表示されてしまう。
こういう場合は、View でフォーム定義を取得して setApp しておく。
$pref_def = $this->af->getDef(‘pref’);
$this->af->setApp(‘pref’, $pref_def['option']);
すると、template では
{$app.pref[$form.pref]}
として、都道府県名のラベルと値を紐付ける事ができる。やったね!
普通にフォーム定義で上記定義使ってる画面はこれでいいけど、フォーム定義なしで、単にDBから取ってきただけの値から都道府県名を表示したい時はどうするんだろう。
プロジェクトの ActionForm ベースクラスで form_template に代入する形で冒頭のコードようなフォーム定義が行なわれていたら
$this->af->form_template['pref'];
とする事で、上記の getDef で取ってきたもの相当は取れるからこれを使えばいいのかな。
プロパティだから、2行に分けなくても
$this->af->setApp($this->af->form_template['pref']['option']);
みたいに書けるし。
2010
03/03
CentOS 5 に Ruby 1.8.7 をセットアップする(ために checkinstall をセットアップする)
先日、弊社内の開発サーバがハードディスクトラブルにより起動不能になりました。
すぐさま別のサーバに環境を構築して引き継ぎを行なったのですが、短期間で行なった応急処置で100%完全に引き継げるはずもなく、ささいなトラブルはいくつか生じているようです。
例えば、先日のFlash Lite の中身を動的に変更するという記事に貼ってあった、サンプルの CGI が出力されなくなってしまいました。当該記事の中で入れた諸々のライブラリが、移転先サーバには入っていないせいですね。
今回はこれらをセットアップしようと思います。とはいえ、以前書いた内容をそのままやるだけだと思っていたんですが…。
まず、移転先サーバには、Ruby や RubyGems のインストールに用いた checkinstall が入っていませんでした。
CentOS 4 だった旧サーバでは、rpmforge のレポジトリを有効にしてやれば、yum コマンドで checkinstall をセットアップ出来たのに、CentOS 5になった移転先サーバではなぜか以下のように “Nothing to do” になってしまいます。
Continue reading »
2010
02/23
Dreamweaver から Subversion を利用する
Dreamweaver は CS4 から Subversion によるバージョン管理に対応しています。
社内のデザイナさん達に、Subversion 管理を布教したいので、まずは評価してみる事にしました。
とはいえ、結構めんどくさかったです…。
社内にある Subversion は、SVN+SSH 以外のアクセス方法を提供していません。
数年前までは WebDAV もあったのですが、諸般の事情で無くなったままです。
Dreamweaver で SVN+SSH を利用するには、割と手がかかります。
以下のような情報を教科書にして設定を行ないました。
- Subversioning in Adobe Dreamweaver CS4
- Dreamweaver CS4でのSubversionの使用 – パート1: Subversionの紹介 | デベロッパーセンター
- Dreamweaver CS4でのSubversionの使用 – パート2: Subversionを使用するためのDreamweaverの設定 | デベロッパーセンター
- Adobe Dreamweaver CS4 * Subversion (SVN) によるファイルの取得とチェックアウト
まずは、Subversioning in Adobe Dreamweaver CS4 の情報に従い、SVN+SSH を使うための事前準備を行ないます。
vi で ~/.subversion/config ファイルの、[tunnels]セクションに以下の内容を追記します。
ssh = $SVN_SSH /usr/bin/ssh
また、ssh の鍵を作っていない人は、ssh-keygen コマンドを使って鍵ペアを作って、SVN+SSH で接続する先のサーバに登録しておかなくてはなりませんが、特に特別な事もない通常の鍵生成&登録手順だったので、そこの詳細は省略します。
次に、Dreamweaver 側の設定を行ないます。
Continue reading »
2010
02/22
Ruby で Excel を弄る
趣味です。
VBA の書き方はわからないけど、Ruby の書き方ならわかるんです。
Ruby で書いたって、win32ole 挟んだ状態で使ったら、そんなに VBA 書くのと変わんないコードになるんだけどね。
今回は、日毎に時間帯別の統計情報が記載されたテキストファイルをもとに整形された Excel ファイルを出力するのが目標。
テキストファイルは、こういう感じの内容。
集計対象名1 —–
2010/02/21 0 15
2010/02/21 1 8
(中略)
2010/02/21 22 21
2010/02/21 23 18集計対象名2 —–
2010/02/22 0 15
2010/02/22 1 8
(中略)
2010/02/22 22 21
2010/02/22 23 18(以下略)
最初に、
集計対象名(スペース)ハイフンx5
のヘッダが来て、それに続いて0時から23時までの
日時(TAB)時間帯(TAB)件数(TAB)
という行が繰り返されるこのセットを一日分として、数日分の内容が繰り返されて、更にそれが集計対象毎にも繰り返される。
そんなテキストデータをパースして、Excel化するのに用いたスクリプトが以下。
Continue reading »
2010
02/10
Flash Lite の中身を動的に変更する
swfmill というツールの存在を知った。swf ファイルと XML ファイルを相互に変換するという。Flash Lite 1.1 の中身を動的に更新したいという声が社内で上がっていた(何年周回遅れで??)ので、それを試しに使ってみる事にした。
サンプルで使う Flash Lite 1.1 のファイルは以下のようなものを用意した。
手抜きだが必要充分だろう。
This movie requires Flash Player 4.0.0 |
http://dev.uniba.jp/~rei/swfmill/test.swf |
swfmill の利用実績は豊富にある。
まずは、Flash4 の仕様に準拠するために文字コードが UTF-8 でない Flash Lite 1.1 に対応するために下記ページで配布されているパッチを当てる必要があるらしい。
2010
02/05
WP-Al-SWFObject プラグイン
一つ前の記事で SWFObject を使いたかったので、こちらのプラグインを入れた。
でも、Open Flash Chart2 を使おうとしたら問題が起きた。
[embedSWF]/blog/wp-content/uploads/2010/02/ofc/open-flash-chart.swf,550,200,,9.0.0,,{“data-file”:”/blog/wp-content/uploads/2010/02/ofc/line-dot.json”}[/embedSWF]※最初の e は本来小文字
のように指定をして、SWFObject を呼び出すのだが、上記の指定が、
<div style="text-align: center; width: 550px; height: 200px; line-height: 200px; background: #ffffff;">
<div id="swfc0ec1">This movie requires Flash Player 9.0.0</div>
</div>
<script type="text/javascript">
swfobject.embedSWF("/blog/wp-content/uploads/2010/02/ofc/open-flash-chart.swf", "swfc0ec1", "550", "200", "9.0.0", "http://rd.uniba.jp/blog/wp-content/plugins/wp-al-swfobject/expressInstall.swf", {“data-file":"/blog/wp-content/uploads/2010/02/ofc/line-dot.json"}, {}, {});
</script>
と展開されてしまい、3行目の “ のところでパースエラーとなってしまう。
2010
02/05
Flash で グラフを書く
以前、案件で使ったライブラリについて書いておく。
Open Flash Chart 2 といって、Flash で書いたグラフをページ内に埋めこめるツール。
シンプルだけど高機能で、色んな種類のグラフが書ける。
単純なグラフはもちろん
棒グラフ(ガラス的装飾付き)とか・・・
円グラフ
こういうのはローソクチャートって言うんだっけ
公式サイトにはこの他にも い ろ い ろ なサンプルがあるみたい。
使い方は続きで
Continue reading »





