バリケンのRuby日記 RSSフィード

2009-08-15

[][][] SinatBBS on GAE/J  SinatBBS on GAE/J - バリケンのRuby日記 を含むブックマーク はてなブックマーク -  SinatBBS on GAE/J - バリケンのRuby日記  SinatBBS on GAE/J - バリケンのRuby日記 のブックマークコメント

Ruby Freaks Lounge:第9回 SinatraとSequel・Hamlで掲示板アプリを作る|gihyo.jp … 技術評論社」という記事にある「SinatBBS」という掲示板アプリを、Google App Engine for Java上でJRubyを使って動かすための、自分用のメモだよ。

ここでの手順は、Windowsで行うことを想定しているよ。

Java SDKのダウンロードとインストール

まだJava SDKをインストールしていない人は、ダウンロードしてインストールしてね。

Java SDKをインストールするには、Java SDKのダウンロードサイトにアクセスして、下のほうにある「JDK 6 Update 16」の右側の「Download」をクリックしてね。Platformは「Windows」を選択してね。

ダウンロードしたインストーラ「jdk-6u16-windows-i586.exe」をダブルクリックすると、インストールが始まるよ。

Google App Engine for Java SDKのダウンロードと展開

まだGoogle App Engine for Java SDKを入手していない人は、ダウンロードしてね。

Google App Engine for Java SDKを入手するには、Google App Engineのダウンロードサイトにアクセスして、「appengine-java-sdk-1.2.2.zip」をクリックしてダウンロードしてね。ダウンロードした「appengine-java-sdk-1.2.2.zip」ファイルは圧縮されているから、Cドライブ直下に展開してね。

sinatbbsディレクトリの作成

コマンドプロンプトを起動して、次のようにコマンドを入力してね

空白を含むパス上だとうまく動かないみたいなので、ここではCドライブ直下に作成しているよ

> cd \
> mkdir sinatbbs
> cd \sinatbbs

jruby-complete-1.3.1.jarのダウンロードと設置

まだ「jruby-complete-1.3.1.jar」を入手していない人は、ダウンロードしてね。入手先はJRubyのサイトだよ。

jruby-complete-1.3.1.jar」をクリックしてダウンロードしたら、先ほど作ったC:\sinatbbsフォルダに配置してね。

WEB-INFフォルダの作成

先ほど作った「sinatbbs」ディレクトリの中に、次のように3つのディレクトリを作成するよ。

> mkdir WEB-INF
> mkdir WEB-INF\gems
> mkdir WEB-INF\lib

Sinatra、DataMapper、Hamlのインストール

JRubygemコマンドを使って、必要となるライブラリを入手するよ。

> set JAVA_HOME=C:\PROGRA~1\Java\jdk1.6.0_16
> set PATH=%JAVA_HOME%\bin;C:\appengine-java-sdk-1.2.2\bin;%PATH%
> java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems sinatra --no-ri --no-rdoc
> java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems addressable --no-ri --no-rdoc
> java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems dm-datastore-adapter --no-ri --no-rdoc
> java -jar jruby-complete-1.3.1.jar -S gem install -i WEB-INF\gems haml --no-ri --no-rdoc
> rmdir /s /q WEB-INF\gems\bin
> del /q WEB-INF\gems\cache\*

jruby-core.jarruby-stdlib.jarlibフォルダに作成

次のようにコマンドを入力して、「jruby-complete-1.3.1.jar」から「jruby-core.jar」と「ruby-stdlib.jar」を作成するよ。ここでは元となる「jruby-complete-1.3.1.jar」は削除しているけど、削除したくない人は他のフォルダにコピーしておいてね。

> mkdir tmp_unpack
> cd tmp_unpack
> jar xf ../jruby-complete-1.3.1.jar
> cd ..
> mkdir jruby-core
> move tmp_unpack\org jruby-core
> move tmp_unpack\com jruby-core
> move tmp_unpack\jline jruby-core
> move tmp_unpack\jay jruby-core
> move tmp_unpack\jruby jruby-core
> cd jruby-core
> jar cf ../jruby-core.jar .
> cd ..\tmp_unpack
> jar cf ../ruby-stdlib.jar .
> cd ..
> rmdir /s /q jruby-core
> rmdir /s /q tmp_unpack
> move jruby-core.jar WEB-INF\lib
> move ruby-stdlib.jar WEB-INF\lib
> del jruby-complete-1.3.1.jar

appengine-api-1.0-sdk-1.2.2.jarのコピー

次のコマンドを入力して、「appengine-api-1.0-sdk-1.2.2.jar」ファイルをコピーするよ。

> copy C:\appengine-java-sdk-1.2.2\lib\user\appengine-api-1.0-sdk-1.2.2.jar WEB-INF\lib

jruby-rack-0.9.4.jarのダウンロードと配置

JRuby-Rackのサイトから「jruby-rack-0.9.4.jar」をダウンロードして、C:\sinatra_on_gae\WEB-INF\libに配置してね。

WEB-INF/start.rbの作成

テキストエディタで次の内容を入力して、WEB-INFフォルダの中にstart.rbという名前で保存してね。

require 'rubygems'
require 'sinatra'
require 'model/comment.rb'

helpers do
  include Rack::Utils; alias_method :h, :escape_html
end

get '/style.css' do
  content_type 'text/css', :charset => 'utf-8'
  sass :style
end

get '/' do
  @comments = Comments.all(:order => [:posted_date.desc])
  haml :index
end

put '/comment' do
  Comments.create(
    :name => request[:name],
    :title => request[:title],
    :message => request[:message],
    :posted_date => Time.now
  )
  redirect '/'
end

WEB-INF/model/comment.rbの作成

テキストエディタで次の内容を入力して、WEB-INFフォルダの中にmodelフォルダを作成して、そこにcomment.rbという名前で保存してね。

require 'dm-core'
require 'dm-aggregates'
require 'dm-types'
require 'dm-datastore-adapter/datastore-adapter'

DataMapper.setup(:datastore,
                 :adapter => :datastore,
                 :database => 'comments')

class Comments
  include DataMapper::Resource
  def self.default_repository_name; :datastore end
  property :id,         Serial
  property :name,       String
  property :title,       String
  property :message,       Text,     :lazy => false
  property :posted_date, DateTime

  def date
    (self.posted_date.new_offset(Rational(3, 8))).strftime("%Y-%m-%d %H:%M:%S")
  end
 
  def formatted_message
    Rack::Utils.escape_html(self.message).gsub(/\n/, "<br>")
  end
end

WEB-INF/views/index.hamlの作成

テキストエディタで次の内容を入力して、WEB-INFフォルダの中にviewsフォルダを作成して、そこにindex.hamlという名前で保存してね。あ、このファイルは日本語を含んでいるから、ファイルを保存するときは文字コードを「UTF-8」に設定してね。

%form{:method => "POST", :action => '/comment'}
  %input{:type => "hidden", :name => "_method", :value => "PUT"}
  %table
    %tr
      %td 名前
      %td 
        %input{:type => "text", :name => "name"}
    %tr
      %td タイトル
      %td
        %input{:type => "text", :name => "title"}
    %tr
      %td 内容
      %td
        %textarea{:name => "message", :cols => 60, :rows => 8}
    %tr
      %td
      %td
        %input{:type => "submit"}

- @comments.each do |comment|
  .comment
    %h2= h comment.title
    .info
      %span.name== by #{h comment.name}
      %span.date== (#{h comment.date})

    .message
      = comment.formatted_message

WEB-INF/views/layout.hamlの作成

テキストエディタで次の内容を入力して、WEB-INFフォルダの中のviewsフォルダの中にlayout.hamlという名前で保存してね。

!!! XML
!!! Strict
 
%html
  %head
    %title SinatBBS
    %meta{:"http-equiv"=>"Content-Type", :content=>"text/html", :charset=>"utf-8"}
    %link{:rel=>"stylesheet", :type=>"text/css", :href=>"/style.css"}
  %body
    %h1 SinatBBS
    != yield

WEB-INF/views/style.sassの作成

テキストエディタで次の内容を入力して、WEB-INFフォルダの中にviewsフォルダの中にstyle.sassという名前で保存してね。

body
  margin: 0px 20%
  padding: 0px

h1
  margin: 1em

form
  border: 1px solid black
  margin: 1em
  padding: 0.5em

.comment
  border: 1px solid black
  margin: 1em
  padding: 0.5em

  h2
    margin: 0px
    font-size: medium
    float: left

  .info
    span.name
      padding-left: 0.5em
      font-size: small
    span.date
      font-size: small

  .message
    margin-top: 1em

WEB-INF/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-INF/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, 'start.rb')
disable :run

require 'start'

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>

開発用サーバの起動

次のコマンドを入力して、開発用サーバを起動してね。

> dev_appserver.cmd .

Webブラウザで開発用サーバにアクセス

http://localhost:8080/にアクセスして、動作確認してね。

Google App Engineにデプロイ

「appengine-web.xml」の「application」と「version」を適切に設定して、次のコマンドを実行してね。

> appcfg.cmd update .
トラックバック - http://rubyist.g.hatena.ne.jp/muscovyduck/20090815