0

湘南台の男のらーめん500円の営業状態を調べるrubygems作った

昨日、男の店主がメルマガで、「急に三田二郎を食べたくなったから昼の営業は休みます」「今神保町で二郎食べたけど、これから用心棒も食べるから夜は19時からになります」と言っていて面白かったから作った。


■インストール

gem install otokonoramen500yen


■使う
gem installすると、otokonoramen500yenというコマンドが使えるようになる。
otokonoramen500yen
実行すると、最新のメルマガの日時と本文が表示される。


これでterminalで作業している時に、ブラウザを開かなくても今日営業しているかパッと調べられるので便利です。


■開発者向け情報
一応gemなので、本文と発行日時を取得できるようにしておいた。
例えば、センサーで取得した自身の健康状態と、男のらーめんの営業状態とを連動させた健康促進システムの開発などへの応用が期待できる。
require 'rubygems'
require 'otokonoramen500yen'
o = Otokonoramen500yen.get
puts o.date
puts o.body
puts o.url

1

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})


■ソースコードとか

1

hugeurlというgemを作った

ふげではなくヒュージ。
tinyurlやbit.lyなどの短縮URLを展開できる。


■インストール

gem install hugeurl


■使う
require 'rubygems'
require 'hugeurl'
puts URI.parse("http://bit.ly/d4VYD2").to_huge
するとhttp://shokai.orgのURI::HTTPインスタンスが返ってくる

もしくは
Hugeurl.get("http://bit.ly/d4VYD2")
でもいい。

展開には http://search.twitter.com/hugeurl?url= を使っている。

0

ShinagawaSeaside

tokyo tyrantのサーバーを起動したり終了したりするrake taskを作った。

名前は、tokyotyrantの周辺のライブラリがmiyazaki resistanceとかそういう名前ばかりだったのでそういう作法なのかなと思って天王洲アイルと迷いつつ品川シーサイドに決めた。


■インストール

sudo gem isntall shinagawaseaside


■使う
Rakefile
require 'rubygems'
require 'shinagawaseaside'

ttdb = [ { :name => 'users', :port => 20010},
         { :name => 'videos',:port => 20011},
         { :name => 'comments', :port => 20012} ]

ShinagawaSeaside::set_tasks(ttdb, :basedir => File.dirname(__FILE__)+'/ttdb')
ShinagawaSeaside::set_tasks するとrake taskが追加される。

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に置いた

0

gemだけで画像をリサイズできるImageResizeを作った

ImageResizeはImageMagickなどの外部プログラムに依存せずに、単体で画像をリサイズできる。ただしJavaの実行環境が必要。


SFCの「革新的ネットサービスの構築」という授業のTAをやっていて、昨日と今日niftyに行って開発合宿をしていた。
そこでいろいろあって、ImageMagickなしで画像のサムネイルを作る方法が無いのか模索していたら、ImageResizeというgemができた。

■インストール

gem install ImageResize


■使う
require 'rubygems'
require 'ImageResize'

# input, output, width, height
Image.resize('big.jpg', 'small.jpg', 40, 40)
これで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で画像処理とかしてみたい。