アーカイブ
im.kayac.comのgem作った
im.kayac.comのAPIを使うためのgemを作った。
im.kayac.comは自分のアプリからiPhoneにpush通知したり、自分のgoogle talkにメッセージを送ったりするのに便利なwebサービスで、俺はよく使ってる。
研究室のwikiの更新情報を自分のケータイに通知したりとか、あとtwitter検索の結果を通知したりとかするアプリの中で使う為にこのgemを作った。Androidケータイがgoogle talkをすごいレスポンスで受信できるので、我ながらいいアプリ作ったと思っている。
■インストール
gem install im-kayac
■使う
require 'rubygems'
require 'im-kayac'
begin
p ImKayac.post("username", "hello world")
rescue => e
STDERR.puts e
end
im.kayac.comの設定でパスワード認証をしているなら、引数で渡す。
ImKayac.post("username", "hello world", {:password => 'your-password'})
秘密鍵認証の場合はこうする。
require 'digest/sha1'
message = 'hello world'
sig = Digest::SHA1.hexdigest(message + 'your-sig')
p ImKayac.post("username", message, {:sig => sig})
■ソースコードとか
hugeurlというgemを作った
ふげではなくヒュージ。
tinyurlやbit.lyなどの短縮URLを展開できる。
■インストール
gem install hugeurl
■使う
require 'rubygems'するとhttp://shokai.orgのURI::HTTPインスタンスが返ってくる
require 'hugeurl'
puts URI.parse("http://bit.ly/d4VYD2").to_huge
もしくは
Hugeurl.get("http://bit.ly/d4VYD2")
でもいい。展開には http://search.twitter.com/hugeurl?url= を使っている。
ShinagawaSeaside
tokyo tyrantのサーバーを起動したり終了したりするrake taskを作った。
名前は、tokyotyrantの周辺のライブラリがmiyazaki resistanceとかそういう名前ばかりだったのでそういう作法なのかなと思って天王洲アイルと迷いつつ品川シーサイドに決めた。
■インストール
sudo gem isntall shinagawaseaside
■使う
Rakefile
require 'rubygems'ShinagawaSeaside::set_tasks するとrake taskが追加される。
require 'shinagawaseaside'
ttdb = [ { :name => 'users', :port => 20010},
{ :name => 'videos',:port => 20011},
{ :name => 'comments', :port => 20012} ]
ShinagawaSeaside::set_tasks(ttdb, :basedir => File.dirname(__FILE__)+'/ttdb')
Rakefileのあるディレクトリの下に ttdb というディレクトリが作られて、
その中にusers.tch, videos.tch, comments.tch というDBができる。pidはusers.pid, videos.pid, comments.pidの中に入る。
% rake -T
rake ttrestart # restart TokyoTyrant server
rake ttstart # start TokyoTyrant server
rake ttstop # stop TokyoTyrant server
中身はRakeでTokyoTyrant serverを起動/終了 – 橋本詳解と大体同じ。(複数サーバー起動できるようにした)
tokyotyrantをソースからインストールすると一緒に入る ttservctl を参考にした。
タスクの名前は初期値がttstart, ttstopだけど、変更もできる
ShinagawaSeaside::set_tasks(ttdb,
:basedir => File.dirname(__FILE__)+'/ttdb',
:start => 'start', # set task name
:stop => 'stop',
:restart => 'restart'
)
俺はyamlで設定ファイルを書いてそこから読み込むようにしている。そうするとアプリからも、どのDBがどのportにあるか見つけやすい。
config.yaml
ttdb :
- name : users
port : 23240
- name : videos
port : 23241
Rakefile
require 'rubygems'
require 'yaml'
require 'shinagawaseaside'
begin
conf = YAML::load open(File.dirname(__FILE__)+'/config.yaml')
rescue
STDERR.puts 'config.yaml load error'
exit 1
end
ShinagawaSeaside::set_tasks(conf['ttdb'], :basedir => File.dirname(__FILE__)+'/ttdb')
■ソースコード
githubに置いた
gemだけで画像をリサイズできるImageResizeを作った
ImageResizeはImageMagickなどの外部プログラムに依存せずに、単体で画像をリサイズできる。ただしJavaの実行環境が必要。
SFCの「革新的ネットサービスの構築」という授業のTAをやっていて、昨日と今日niftyに行って開発合宿をしていた。
そこでいろいろあって、ImageMagickなしで画像のサムネイルを作る方法が無いのか模索していたら、ImageResizeというgemができた。
■インストール
gem install ImageResize
■使う
require 'rubygems'これで40×40ピクセルに縮小される。
require 'ImageResize'
# input, output, width, height
Image.resize('big.jpg', 'small.jpg', 40, 40)
縦横のアスペクト比が1:1ではない画像の場合、アスペクト比を保ったまま長辺の方にあわせて縮小する。
■ソースコード
githubに置いた。
http://github.com/shokai/ImageResize-ruby
■実装
本体はJava。
標準実行環境にJPEGやGIFやBITMAPなど様々な画像フォーマットの読み書き機能を含んでいる環境というと、Javaと.NETとopenFrameworksしか思いつかなかった。
その中でいちばん色々なマシンにインストールされていそうで、配布が容易な物を選んだらJavaになった。
Javaでの画像の扱いは.NET並に簡単。java.awtとjavax.imageioの下に色々充実しているのでそれらを使えばいい。
ImageResize.java
import javax.imageio.*;
import java.io.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.util.regex.*;
class ImageResize{
public ImageResize(){
}
public static void main(String args[]){
if(args.length < 4){
System.out.println("ImageResize in.jpg out.jpg 320 320");
System.exit(1);
}
ImageResize app = new ImageResize();
if(app.resize(args[0], args[1], Integer.parseInt(args[2]), Integer.parseInt(args[3]))){
System.out.println(args[1]);
}
}
public boolean resize(String fname_in, String fname_out, int max_width, int max_height){
System.out.println(fname_in);
BufferedImage img = null;
try {
img = ImageIO.read(new File(fname_in));
}
catch (Exception e) {
e.printStackTrace();
img = null;
}
int width, height;
if(img.getWidth() < img.getHeight()){
height = max_height;
width = img.getWidth() * max_height / img.getHeight();
}
else{
width = max_width;
height = img.getHeight() * max_width / img.getWidth();
}
System.out.println(img.getWidth() + "x" +img.getHeight() + " => " + width + "x" + height);
BufferedImage img_resized = new BufferedImage(width, height, img.getType());
AffineTransformOp ato = new AffineTransformOp(AffineTransform.getScaleInstance((double)width / img.getWidth(),
(double)height / img.getHeight()),
null);
ato.filter(img, img_resized);
String format = Pattern.compile("^.+\\.(.+)$").matcher(fname_out).replaceAll("$1");
boolean result = false;
try {
result = ImageIO.write(img_resized, format, new File(fname_out));
}
catch (Exception e) {
e.printStackTrace();
result = false;
}
return result;
}
}
■参考
今回は使わなかったが、Java Advanced Imaging (JAI) APIというのが標準実行環境には含まれていないけどSunが作っていて、かなり充実しているらしい。
Javaランタイムも速くなってきているらしいしScalaで画像処理とかしてみたい。
ArgsParserをrubygemsに登録した
車輪の再発明臭がヤバイが、コマンドラインの引数のパーサを作ったのでrubygemsに登録した。はじめてgem登録した。
gemでインストールできる。
gem update --system
gem install ArgsParser
newgemコマンドでgemを作ってrubygems.orgに登録し、一応rspecでtestも書いた。
gemはrubyforge.orgで公開するのが普通だったけど、2年ぐらい前からgithubでgemが作れる様になったので新しいプロジェクトはみんなgithubに行って、2009年秋?頃にgithubでgemがビルドできなくなったからかrubygems.orgでやってねという事になったらしい。
なのでリポジトリはいつも使っているmercurialにしてbitbucket.orgで公開する事にした。
shokai / argsparser-ruby / overview — bitbucket.org
既にgemにはいくつかCのgetopt風なARGVのparserがあるけど、なんとなくインタフェースが好きじゃないので自分が欲しい物を作った。
- –help -debug等のオプションの有無を判別する
- -x 320 -y 240 等のパラメータ(key value)を取得する
- -hと-helpのように省略名称が関連づけられていれば同じ物として扱う
- -helpと—helpのようなハイフンの数の違いを無視して、全て :help でアクセスできる
- ruby math.rb add -a 10 -b 25 の”add”のような、第一引数を取り出す
- パラメータ名にコメント文を付ける(-helpで起動した時の引数の説明文に使う)
parseすると、第一引数(String)とパラメータ(Hash)が返ってくる。第一引数がない(いきなりパラメータが来た)場合は、第一引数はnilになる。
example.rb
#!/usr/bin/env ruby
require 'rubygems'
require 'ArgsParser'
# 必要なパラメータ名を登録する
parser = ArgsParser.parser
parser.bind(:help, :h, "show help") # name, shortname, comment for help
parser.bind(:frame, :f, "frame image (required)")
parser.bind(:message, :m, "message (required)")
parser.bind(:size, :s, "size (required)")
parser.comment(:min, "minimum size") # add comment for help
parser.comment(:max, "maximum size")
parser.comment(:debug, "debug mode")
# parseして、引数が足りてるか、help表示指定が無いかチェック
first, params = parser.parse(ARGV)
if parser.has_option(:help) or !parser.has_params([:frame, :message, :size])
puts parser.help
puts 'e.g. ruby example.rb -f frame.png -m "hello world" -s 320x240 -debug'
exit 1
end
if first
puts 'first arg : ' + first # 第一引数
end
if parser.has_param(:size)
puts 'size : ' + params[:size] # -sでも-sizeでも :size でアクセスできる
end
# 全ての引数を表示
p params
実行してみる
ruby example.rb hoge -f frame.png -m "hello world" -s 320x240 -debug結果
first arg : hoge
size : 320x240
{:message=>"hello world", :size=>"320x240", :debug=>true, :frame=>"frame.png"}

最近のコメント