June 16, 2009

Termtter に HTTP サーバー機能を提供するプラグインを作りました!

Termtter に HTTP サーバー機能を提供するプラグインを作りました!
HTTP 経由でコマンドを実行することができます。

こんな風にしてブラウザからメッセージをポストすることもできます。

Picture 16
Uploaded with plasq’s Skitch!

便利ですね!

使い方

プラグインの読み込み

設定ファイル(~/.termtter/config)に以下の太字部分を追記。

Termtter::Client.init do |t|
...
  t.plug 'http_server'
...
end

もしくは Termtter のプロンプト上で以下を実行。

> plug 'http_server'

デフォルトのポートは 5678 です。
ポートを変えたい場合、例えば設定ファイルに config.plugins.http_server.port = 3000 と書くと 3000 番ポートを使用します。

コマンドの実行

リクエストされたパスの「/」を除いた部分がコマンドとして実行されます。
「update test」というコマンドを実行したい場合は「/update test」というリクエストを投げます。
パスは当然 URI としてエスケープしてやる必要があります。
なので以下のようになります。

http://localhost:5678/update%20test
June 11, 2009

Termtter Tシャツできました!

ついにできました!
Termtter Tシャツが!

DSCF6444.JPG

DSCF6447.JPG

こちらから買えます。

jugyoさんのTシャツ ID:8061

ちなみに Tシャツが売れても僕には一銭も入ってきませんw

また、Termtter の開発をやりたいかたはこちらからどうぞ。

http://github.com/jugyo/termtter/

May 22, 2009

近況

最近、自宅ではひたすらプログラミングしてます。
時間さえあればプログラミングしてるのでブログを書く習慣がなくなりつつあります。

そういえば「More Joel on Software」を読みましたけど、相変わらず面白かったです。

ところで最近こんなの作りました。

Gitki

https://github.com/jugyo/gitki/tree

git を使って更新する wiki です。
ブラウザからは更新できません。
デモ: http://gitki.oyguj.org/

ifchanged

https://github.com/jugyo/ifchanged/tree

引数に渡したファイルが更新されたときに「何か」を実行するためのコマンドです。

% ifchanged ./**/*.html --do 'open %'

みたいにして使います。

g

https://github.com/jugyo/g/tree

ruby の組み込み関数の「p」のような動きをするメソッド「g」を提供するライブラリです。
オブジェクトを inspec した結果を growl で表示します。

Picture 13.png

May 1, 2009

Sequel を試す

インストール

sudo gem install sequel

使ってみる

初期化処理を行い、テーブルを作成し、データをいくつか投入してみます。

require 'rubygems'
require 'sequel'

# initialize
DB = Sequel.sqlite('test.db')

# create database
DB.create_table :items do
  primary_key :id
  String :name
  Float :price
end

# insert data
items = DB[:items]
items << {:name => 'foo', :price => 100}
items << {:name => 'bar', :price => 200}

まあ、何やってるかだいたいわかりますよね。

Sequel コンソール

以下のようにしてコンソールを立ち上げることができます。

sequel sqlite://test.db

諸々の初期化処理を行った状態で irb が起動してるんだと思います。
こういうツールが用意されてるっていいですね!

データの取得

上記で作成したデータをいろんなやり方で取得してみます。
Sequel コンソールで実行しました。

# count
> DB[:items].count
=> 2

# select all
> DB[:items].all
=> [{:price=>100.0, :name=>"foo", :id=>1}, {:price=>200.0, :name=>"bar", :id=>2}]

# select first
> DB[:items].first
=> {:price=>100.0, :name=>"foo", :id=>1}

# select id = 2
> DB[:items][:id => 2]
=> {:price=>200.0, :name=>"bar", :id=>2}

# select price = 200
> DB[:items].filter(:price => 200).all
=> [{:price=>200.0, :name=>"bar", :id=>2}]

# select price > 100
> DB[:items].filter{|i| i.price > 100}.all
=> [{:price=>200.0, :name=>"bar", :id=>2}]

# select price < 100
> DB[:items].filter('price < ?', 200).all
=> [{:price=>100.0, :name=>"foo", :id=>1}]

# select by sql
> DB['select * from items'].all
=> [{:price=>100.0, :name=>"foo", :id=>1}, {:price=>200.0, :name=>"bar", :id=>2}]

なんとなくイメージはつかめましたか?

TermColor に機能追加

TermColor にちょっとした機能を追加しました。
機能追加ってほどでもないんだけど。

以下を実行すると、

ruby -rubygems -e 'require "termcolor"; TermColor.test'

以下が出力されます。

http://gyazo.com/729e6cf622e5e4c20344e5ae0b5441f0.png

つまり、カラーコードが確認できます。
便利ですね!

関連エントリ
TermColor – コンソールへの出力を HTML っぽく色付け♪

TermColor
http://github.com/jugyo/termcolor

April 26, 2009

Termtter の設定ファイルの書式を少し変えました(HEAD)

Termtter の設定ファイルの書式を少し変えました(古いままでも一応動くはずです)。
新しい書式は以下のようになります。

config.user_name = 'jugyo'
config.password = 'xxxxxxxx'

Termtter::Client.init do |t|
  t.plug 'log'
  t.plug 'confirm'
  t.plug 'growl'
  t.plug 'stdout'
  t.plug 'standard_commands'
  t.plug 'auto_reload'
end

プラグインを読み込むやりかたが変わっています。
今までみたいに plugin メソッドでプラグインを読み込むのではなく、Termtter::Client.init に渡すブロックの中で、Termtter::Client (引数に渡ってくる t は Termtter::Client そのもの)の plug メソッドを呼んでプラグインを読み込む形になります。
この変更は次のバージョンに反映されると思います。

なんでこうしたかというと、config を読み込んで ライブラリ等の初期化を行った後にプラグインを読みむようにしたかったからです。

April 20, 2009

Sinatra が Google App Engine で動くまで

(注: Google App Engine を GAE と略すことがあります。)

Sinatra を Google App Engine で動かしてみました。

Github にすぐに動かせるものを置いておいたので、手っ取り早く試したい人はここからソースを取ってきて動かしてみるといいと思います。
appengine-java-sdk は別途必要です。

http://github.com/jugyo/sinatra_on_gae/tree/master

詳細は同梱されている README を参照してくだい。

以下は、ちゃんと手順を追って試してみたい人向けの解説です。

SDK のダウンロード

SDK をマシンに入れておく必要があります。
以下から appengine-java-sdk-1.2.0.zip というのをダウンロードして適当な場所に解凍してください。

http://code.google.com/appengine/downloads.html

PATH の設定

SDK の bin ディレクトリを PATH に追加しておきます。
コマンドを実行するときにフルパスを指定するのが面倒なので。

例:

export PATH=$PATH:~/src/jruby/appengine-java-sdk-1.2.0/bin

アプリケーションのフォルダを作成

フォルダをいくつか作ります。

cd sinatra_on_gae
mkdir WEB-INF
mkdir WEB-INF/gems WEB-INF/lib

ライブラリのインストール

必要なライブラリを gem でインストールします。
その際、-i オプションでディレクトリを指定します。
さらに、rdoc や ri はいらないので –no-rdoc –no-ri オプションも付けておきます。

gem install -i WEB-INF/gems sinatra --no-rdoc --no-ri

以下のファイルは不要なので削除しておきます。

rm -rf WEB-INF/gems/bin WEB-INF/gems/cache/*

jar ファイルの用意

WEB-INF/lib に以下の jar ファイルを置きます。

appengine-api-1.0-sdk-1.2.0.jar
jruby-core.jar
ruby-stdlib.jar
jruby-rack-0.9.4.jar

appengine-api-1.0-sdk-1.2.0.jar は SDK に含まれているライブラリで、 jruby-core.jar と ruby-stdlib.jar は、Github から取ってきた JRuby をビルドして必要なものだけ抜き出したものです。
jruby-rack-0.9.4.jar も Github から取ってきてビルドしました。

Sinatra アプリケーションを作成

Sinatra 上で動かすアプリケーションを作ります。

WEB-INF/app.rb

require 'rubygems'
require 'sinatra'

get '/' do
  'Hello World!!'
end

やっぱり Sinatra はシンプルでいいですね〜。

appengine-web.xml の作成

GAE アプリケーションとしての設定を appengine-web.xml というファイルに書きます。

WEB-INF/appengine-web.xml

<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <application>sinatra_on_gae</application>
    <version>1</version>
    <static-files />
    <resource-files />
    <sessions-enabled>false</sessions-enabled>
    <system-properties>
      <property name="jruby.management.enabled" value="false" />
      <property name="os.arch" value="" />
      <property name="jruby.compile.mode" value="JIT"/> <!-- JIT|FORCE|OFF -->
      <property name="jruby.compile.fastest" value="true"/>
      <property name="jruby.compile.frameless" value="true"/>
      <property name="jruby.compile.positionless" value="true"/>
      <property name="jruby.compile.threadless" value="false"/>
      <property name="jruby.compile.fastops" value="false"/>
      <property name="jruby.compile.fastcase" value="false"/>
      <property name="jruby.compile.chainsize" value="500"/>
      <property name="jruby.compile.lazyHandles" value="false"/>
      <property name="jruby.compile.peephole" value="true"/>
   </system-properties>
</appengine-web-app>

web.xml の作成

Web アプリケーションの設定を web.xml に記述します。

WEB-INF/web.xml

<!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

  <context-param>
    <param-name>public.root</param-name>
    <param-value>/</param-value>
  </context-param>

  <context-param>
    <param-name>rackup</param-name>
    <param-value>require 'rubygems'
require 'sinatra'

root_dir = File.dirname(__FILE__)

#set :environment, :production
set :environment, :development
set :root,        root_dir
set :app_file,    File.join(root_dir, 'app.rb')
disable :run

require 'app'

run Sinatra::Application
</param-value>
  </context-param>

  <context-param>
    <param-name>jruby.min.runtimes</param-name>
    <param-value>1</param-value>
  </context-param>

  <context-param>
    <param-name>jruby.max.runtimes</param-name>
    <param-value>1</param-value>
  </context-param>

  <context-param>
    <param-name>jruby.init.serial</param-name>
    <param-value>true</param-value>
  </context-param>

  <filter>
    <filter-name>RackFilter</filter-name>
    <filter-class>org.jruby.rack.RackFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>RackFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <listener>
    <listener-class>org.jruby.rack.RackServletContextListener</listener-class>
  </listener>

</web-app>

sinatra のソースをちょっとだけ修正する必要があります。
WEB-INF/gems/gems/sinatra-0.9.1.1/lib/sinatra.rb の8行目です

use_in_file_templates!

#use_in_file_templates!

use_in_file_templates! というのはおそらく、ファイルの中にテンプレートを書いておける機能にまつわるメソッドだと思います。
ま、いらないと思います。

GAE のアプリとして起動する

さて、以上でアプリケーションを動かす準備が整いました。
以下のようにして起動するとこができます。

dev_appserver.sh .

ちなみに、起動の際には WEB-INF ディレクトリが置かれているディレクトリを指定する必要があります。

普通の Ruby で起動する

普通の Ruby でも当然動きます。

GEM_HOME=WEB-INF/gems ruby ./WEB-INF/app.rb

デプロイ

appengine-web.xml の application と version を適切に設定した上で以下を実行するとデプロイできます。

appcfg.sh update .

当然、Google App Engine のアカウントを持っていてかつ Java が使えるようなっている必要があります。

デモ

以下で実際に動かしてます(一週間くらいは動かしておくつもりです。Hello World!! しか出ませんけどね!)。

http://jugyo-test.appspot.com/

参考:
http://blog.bigcurl.de/2009/04/running-sinatra-apps-on-google.html