目次
島根県CMS
「島根県CMS」は、Ruby on Railsで作られた行政機関向けのCMSである。 オープンソースソフトウェア(ライセンスはGPL)であり、無償で利用できる。
- 島根県CMSに関する考察 http://d.nishimotz.com/archives/64
- このdokuwiki文書に関するご報告 http://d.hatena.ne.jp/nishimotz/20090809/1249808227
- 本記事の作業のソースコード http://github.com/nishimotz/pref_shimane_cms/
- 島根県CMSを参考にスクラッチから開発。GalateaTalkも使用「徳島県がRubyの独自開発CMS「Joruri」でサイトを刷新,OSSとして公開へ」 http://bit.ly/6KugCP
音声合成エンジン (gtalk) の利用
GalateaTalk (gtalk) 関連の利用状況を確認する。 作業環境は Ubuntu Linux 9.04 である。日常的に Galatea Toolkit や Ruby on Rails の開発に使っている環境。
2009年8月8日現在の最新版である 1.1.0 のソースを確認してみる。
$ tar xvfz pref-shimane-cms-1.1.0.tar.gz $ cd pref-shimane-cms-1.1.0
音声合成関連は tool/gtalk/ にある。
$ ls -1 tool/gtalk/ gtalk/ morph/ rubi-adder/ speakers/ voice-synthesis/
rubi-adder は gtalk と直接関係ないと思われるが、テキスト解析を伴うので この場所に置かれている模様。
tool/gtalk/gtalk/README.ipadic には西本が書いた ipadic 対応化のドキュメントがある。 かつて unidic の辞書は非常に語彙サイズが小さく、ipadic を使うことは現実的な利用の手段として 検討に値するものだった。また、現時点でも unidic のライセンスはフリーではなく、 島根県CMSでは「GPL 互換」にするために ipadic が選択されたと考えられる。
$ head -15 tool/gtalk/gtalk/ssm.conf # configuratiuon file for gtalk (GalateaTalk) # path name of 'chasen' CHASEN: /usr/bin/chasen # configuration file for 'chasen' CHASEN-RC: ./chasenrc # command of running 'chaone' #CHAONE: ../morph/chaone-1.2.0/chaone CHAONE: ../voice-synthesis/chaone-filter.rb # path name of 'chaone.xsl' (only for library-based version) #CHAONE-XSL-FILE: ../chaone-1.2.0/chaone_t_EUC-JP.xsl
voice-synthesis ディレクトリには、Ruby から音声合成を呼び出すラッパーなどがあるようだ。
$ ls -1 tool/gtalk/voice-synthesis/ chaone-filter.rb* speak.rb* speakout.cgi* tests/ voice_synthesis.cgi* voice_synthesis.html voice_synthesis.rb
CGIファイルはデバッグ用であるらしく、このままでは動かない。
$ ruby tool/gtalk/voice-synthesis/speakout.cgi tool/gtalk/voice-synthesis/speakout.cgi:7:in `chdir': No such file or directory - /home/kouji/work/pref-shimane-cms/gtalk/gtalk (Errno::ENOENT) from tool/gtalk/voice-synthesis/speakout.cgi:7
いろいろいじる前に git で commit しておこう。
$ git init $ git add . $ git commit -m "initial" -a
下記のように直した。
diff --git a/tool/gtalk/voice-synthesis/speakout.cgi b/tool/gtalk/voice-synthesis/speakout.cgi index ddc106a..5ecf456 100755 --- a/tool/gtalk/voice-synthesis/speakout.cgi +++ b/tool/gtalk/voice-synthesis/speakout.cgi @@ -4,7 +4,7 @@ require 'cgi' text = 'こんにちは、赤ちゃん。' -Dir.chdir('/home/kouji/work/pref-shimane-cms/gtalk/gtalk') do +Dir.chdir(File.join(File.dirname(__FILE__), "../gtalk")) do ENV['LANG'] = 'ja_JP.EUC-JP' IO.popen("./gtalk -C ssm.conf > /var/tmp/log", "w") do |f| f.puts("set Text = #{text}")
再度実行。gtalk がコンパイルされていないことに気づく。
$ ruby tool/gtalk/voice-synthesis/speakout.cgi sh: ./gtalk: not found
doc/INSTALL を見てみると。。
==== 音声合成プログラムの設定 音声合成プログラムgtalk, chaoneをコンパイルします。 $ cd /var/share/cms/tool/gtalk/gtalk $ sudo -u www-data ./configure $ sudo -u www-data make $ cd /var/share/cms/tool/gtalk/morph/chaone-1.2.0 $ sudo -u www-data ./configure $ sudo -u www-data make
いまはTTS単体での動作確認が目的なので、横着して sudo しないでコンパイルしておく。
$ pushd tool/gtalk/gtalk/ $ ./configure ; make $ popd
実行すると今度は kakasi と ipadic がないと怒られる。
$ ruby tool/gtalk/voice-synthesis/speakout.cgi ../voice-synthesis/chaone-filter.rb:3:in `require': no such file to load -- kakasi (LoadError) from ../voice-synthesis/chaone-filter.rb:3 /usr/bin/chasen: /usr/share/chasen/dic/ipadic/user.da: No such file or directory (offline mode: enter name=value pairs on standard input)
いままで doc/INSTALL の手順を完全に無視していたので当たり前なのだが、 あえて TTS が依存しているパッケージを確認したかったのだ。
そもそも kakasi が必要なのはなぜだろう。
tool/gtalk/voice-synthesis/chaone-filter.rb を見てみる。
def to_katakana(str) return Kakasi.kakasi('-JK -HK', str).gsub(/[,.]/e, '') end
chasen+ipadic での解析では不十分な変換を補っているらしい。
$ sudo apt-get install kakasi libkakasi-ruby1.8
kakasi を長い間使っていないのでオプションの意味を忘れてしまった。確認しておこう。 gnome-terminal で EUC-JP に設定しておく。
$ LANG=ja_jp.euc-jp;echo "今日はいい天気。ヤッホー" | kakasi -HK 今日ハイイ天気。ヤッホー $ LANG=ja_jp.euc-jp;echo "今日はいい天気。ヤッホー" | kakasi -JK コンニチハいいテンキ。ヤッホー $ LANG=ja_jp.euc-jp;echo "今日はいい天気。ヤッホー" | kakasi -JK -HK コンニチハイイテンキ。ヤッホー
気を取り直して。chasen と ipadic はすでに入っている。
$ ruby tool/gtalk/voice-synthesis/speakout.cgi /usr/bin/chasen: /usr/share/chasen/dic/ipadic/user.da: No such file or directory (offline mode: enter name=value pairs on standard input)
どうやらユーザ辞書を使うことが前提になっている。 でもこれは chasenrc で指定されているので、とりあえず外しておこう。
--- a/tool/gtalk/gtalk/chasenrc +++ b/tool/gtalk/gtalk/chasenrc @@ -12,7 +12,7 @@ ;;; ;;; dictionary /辞書 ;;; -(DADIC chadic user) +(DADIC chadic) ; user ;;;
lame を入れる。doc/INSTALL では make install することになっているが、 Ubuntu のパッケージを使おう。
$ sudo apt-get install lame
$ echo "" | ruby tool/gtalk/voice-synthesis/speakout.cgi > /mnt/hgfs/work/_out.mp3
仮想マシンのホスト環境である Windows で聴いてみる。 http サーバの応答なので先頭にテキストが2行くっついているが、それを取り除いても音がおかしい。
$ play -r 16000 -t sw /var/tmp/14765.raw
エンコードする前の音は問題ないようだ。バイトオーダーが逆?
speakout.cgiを見てみよう。
system("lame -r -s 16 -m m -x -S --silent -b 32 --cbr /var/tmp/#{$$}.raw /var/tmp/#{$$}.mp3")
doc/INSTALL では lame 3.97 を入れているが、apt-get で入れたのは 3.98 である。
$ lame -v LAME 32bits version 3.98 (http://www.mp3dev.org/) usage: lame [options] <infile> [outfile] <infile> and/or <outfile> can be "-", which means stdin/stdout. Try: "lame --help" for general usage information or: "lame --preset help" for information on suggested predefined settings or: "lame --longhelp" or "lame -?" for a complete options list
気を取り直して、もう一つのデモらしいスクリプトを試そう。
$ ruby tool/gtalk/voice-synthesis/voice_synthesis.rb tool/gtalk/voice-synthesis/voice_synthesis.rb:136:in `write': Broken pipe (Errno::EPIPE) from tool/gtalk/voice-synthesis/voice_synthesis.rb:136:in `synthesize'
けっきょく「lameのパスを正しく与える」「lameの-xオプションを外す」の2つで、音が出るようになった。
--- a/tool/gtalk/voice-synthesis/voice_synthesis.rb +++ b/tool/gtalk/voice-synthesis/voice_synthesis.rb @@ -80,9 +80,10 @@ class VoiceSynthesis @gtalk_path = File.expand_path('../gtalk/gtalk', File.dirname(__FILE__)) @gtalk_options = ['-C', 'ssm.conf', '2>', '/dev/null'] - @lame_path = '/usr/local/bin/lame' + @lame_path = `which lame`.chomp # '/usr/local/bin/lame' @lame_options = - ['-r', '-s', '16', '-m', 'm', '-x', '-S', '-b', '32', '--cbr', + ['-r', '-s', '16', '-m', 'm', # '-x', + '-S', '-b', '32', '--cbr', '--scale', '1.5', '-', '-', '2>', '/dev/null'] @max_part_length = 1000 @logger = nil
$ ruby tool/gtalk/voice-synthesis/voice_synthesis.rb > /var/tmp/_hoge.mp3 $ play /var/tmp/_hoge.mp3
で、この VoiceSynthesis クラスは本当に使われているのか?
$ find -name *.rb | xargs grep VoiceSynthesis ./tool/gtalk/voice-synthesis/tests/voice_synthesis_test.rb:class VoiceSynthesisTest < Test::Unit::TestCase ./tool/gtalk/voice-synthesis/tests/voice_synthesis_test.rb: res = VoiceSynthesis.replace_phone_number('(090)1234-5678') { |s| ./tool/gtalk/voice-synthesis/tests/voice_synthesis_test.rb: res = VoiceSynthesis.replace_phone_number('[(090)1234-5678]') { |s| ./tool/gtalk/voice-synthesis/tests/voice_synthesis_test.rb: res = VoiceSynthesis.replace_phone_number(test_data) { |s| ./tool/gtalk/voice-synthesis/tests/voice_synthesis_test.rb: VoiceSynthesis.replace_phone_number(test_data) do |s| ./tool/gtalk/voice-synthesis/voice_synthesis.rb:class VoiceSynthesis ./tool/gtalk/voice-synthesis/voice_synthesis.rb: vs = VoiceSynthesis.new
あれ、使われてない? と焦るが、あった。
$ find . | xargs grep VoiceSynthesis ./tool/export: vs = VoiceSynthesis.new ...
拡張子なしの tool/export を見てみると CMSExport クラスで create_mp3(arg, tmp_id) というメソッドを発見。 ここで VoiceSynthesis クラスの html2m3u メソッドが使われている。 VoiceSynthesis クラスに戻って確認すると、html2m3u メソッドが synthesize_html メソッドを呼び出し、 ここでさらに synthesize メソッドが呼ばれる。
だいたい GalateaTalk の使われ方に納得できたのだが、VoiceSynthesis クラスから HTML 依存の機能を追い出すように リファクタリングして、VoiceSynthesys クラスを汎用化する(railsプラグインあるいはgemにする) と喜ばれるかも知れない。
そういえば ruby-chasen をインストールしなかったが、問題なかったようだ。
chasen は gtalk のサブプロセスとして呼ばれるだけだから、現段階では、必要なくて当然な気もするが。。
lib/filter.rb
CMSではあらゆるテキストが入力されることを想定しなければならず、 GalateaTalkのような(商用品質とは言い難い)TTSがあらゆる入力に対して 頑健ではないという現実を、「島根県CMS」がどう実装で補っているのだろう?
日本語の encoding の問題、機種依存文字の変換などを担っている箇所を見つけた。 VoiceSynthesys クラスからも使われている Filter モジュール lib/filter.rb である。
if __FILE__ == $0 a = "\xe3\x81\x82\xe3\x80\x9c\xe2\x91\xa0\xe2\x85\xa0\xe3\x81\x84"; puts a puts Filter::convert_non_japanese_chars(a) end
のように puts a を書き加えて実行してみた。
$ ruby lib/filter.rb あ〜①Ⅰい あ〜<span class="invalid">①</span>Iい
2文字目は Ubuntu の「端末」では「~」(いわゆる「から」記号)に見えるのだが、 Windowsのブラウザにコピペすると「上下が逆になったチルダ」である。
3~4文字目のWindows依存文字「マル1」「ギリシャ数字の1」を 機種非依存文字に変換している。機種に依存せずブラウザでコンテンツを表示するためには 必要な機能である。ただし音声化を想定した前処理としては機能不足に思える。
postgres を動かす
そろそろシステムを動かしてみよう。 Ubuntu で「できるだけ手抜きをしながら」そして「できるだけ中身を理解しながら」やってみる。 まず postgres だ。 作業マシンではいままで sqlite3 と mysql5 をかじっていたが、この機会に環境設定しておく。
$ sudo apt-get install postgresql
Version: 8.3.7-1 がインストールされた。 doc/INSTALL によれば createuser を使え、とのこと。 /usr/bin/createuser である。postgres-xxx でも pg-xxでもなく、この名前である。
www-data というユーザ名が指定されているのだが、あとで別のシステムの開発に使いたいので、 cms-data にしておこう。
$ sudo -u postgres /usr/bin/createuser cms-data Shall the new role be a superuser? (y/n) y createuser: could not connect to database postgres: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
怒られてしまった。 多少やり方を変えてみた。
$ sudo -u postgres /usr/lib/postgresql/8.3/bin/createuser -h localhost cms-data Shall the new role be a superuser? (y/n) y createuser: could not connect to database postgres: could not connect to server: Connection refused Is the server running on host "localhost" and accepting TCP/IP connections on port 5432?
たいして変わらない。そういえば initdb しなくてよかったのだろうか、と気になる。
$ sudo -u postgres /usr/lib/postgresql/8.3/bin/initdb -D /var/lib/postgresql/data The files belonging to this database system will be owned by user "postgres". This user must also own the server process. The database cluster will be initialized with locale ja_JP.UTF-8. The default database encoding has accordingly been set to UTF8. initdb: could not find suitable text search configuration for locale ja_JP.UTF-8 The default text search configuration will be set to "simple". ... Success. You can now start the database server using: /usr/lib/postgresql/8.3/bin/postgres -D /var/lib/postgresql/data or /usr/lib/postgresql/8.3/bin/pg_ctl -D /var/lib/postgresql/data -l logfile start
後者がデーモン起動っぽいのでやってみる。
$ sudo -u postgres /usr/lib/postgresql/8.3/bin/pg_ctl -D /var/lib/postgresql/data -l logfile start server starting
これでサーバが動くのではないか? psql というコマンドの存在を思い出した。
$ sudo -u postgres psql -h localhost -l List of databases Name | Owner | Encoding -----------+----------+---------- postgres | postgres | UTF8 template0 | postgres | UTF8 template1 | postgres | UTF8 (3 rows)
動いたようだ。
$ sudo /etc/init.d/postgresql-8.3 status
/etc/init.d は無反応なのが気になるが。
気を取り直して。
$ sudo -u postgres /usr/lib/postgresql/8.3/bin/createuser -h localhost cms-data Shall the new role be a superuser? (y/n) y
rails 用のデータベース3兄弟を作る。 doc/INSTALL に書かれている手順と異なり、sudo -u postgres でなくてはならない。 cms-data は Lunux のユーザアカウントではなく、postgres の中のアカウントである。 以前はこのあたりを密に連動させていた気がするが。。
$ sudo -u postgres /usr/bin/createdb -U cms-data cms_test -EUNICODE $ sudo -u postgres psql -h localhost -l List of databases Name | Owner | Encoding -----------+----------+---------- cms_test | cms-data | UTF8 postgres | postgres | UTF8 template0 | postgres | UTF8 template1 | postgres | UTF8 (4 rows)
引き続き。
$ sudo -u postgres /usr/bin/createdb -U cms-data cms_development -EUNICODE $ sudo -u postgres /usr/bin/createdb -U cms-data cms_production -EUNICODE $ sudo -u postgres psql -h localhost -l List of databases Name | Owner | Encoding -----------------+----------+---------- cms_development | cms-data | UTF8 cms_production | cms-data | UTF8 cms_test | cms-data | UTF8 postgres | postgres | UTF8 template0 | postgres | UTF8 template1 | postgres | UTF8 (6 rows)
ここまでやって思い出したが、最近の rails なら rake db:create:all すればいいところだ。。 rails のバージョンアップがどこまで可能かどうかも検討課題ということにしておこう。
script/server で動かしてみる
あらためて rails の作業に取りかかる。
$ cp config/database.yml.example config/database.yml $ cp config/cms.yml.example config/cms.yml
最近(たぶん1.2以降)の rails なら db:migrate だがここは rails 1.0 あたりの流儀で。。
$ rake migrate rake aborted! no such file to load -- postgres
postgres という gem が入ってないようだ。
$ sudo gem install postgres Building native extensions. This could take a while... ERROR: Error installing postgres: ERROR: Failed to build gem native extension. /usr/bin/ruby1.8 extconf.rb extconf.rb:46: command not found: pg_config --includedir extconf.rb:53: command not found: pg_config --libdir checking for main() in -lpq... no *** extconf.rb failed ***
たぶん postgresql の開発パッケージが必要なのだろう。
$ sudo apt-get install libpq-dev $ sudo gem install postgres Building native extensions. This could take a while... Successfully installed postgres-0.7.9.2008.01.28 1 gem installed Installing ri documentation for postgres-0.7.9.2008.01.28... Installing RDoc documentation for postgres-0.7.9.2008.01.28...
無事に終わったので migrate に戻る。
$ rake migrate It may take a while. Please wait.
$ rake create_session_table $ ./script/server
いまさらだが postgres の動作確認。
$ ps ax | grep postgres 27964 pts/0 S 0:00 /usr/lib/postgresql/8.3/bin/postgres -D /var/lib/postgresql/data 27966 ? Ss 0:00 postgres: writer process 27967 ? Ss 0:00 postgres: wal writer process 27968 ? Ss 0:00 postgres: autovacuum launcher process 27969 ? Ss 0:00 postgres: stats collector process 31411 ? Ss 0:00 postgres: postgres cms_development [local] idle 32626 pts/0 S+ 0:00 grep postgres
http://localhost:3000/ いってみよう。
MissingSourceFile in <controller not set>#<action not set> no such file to load -- chasen RAILS_ROOT: script/../config/..
やっと chasen gem の出番らしい。
ruby-chasen
別のコンソールで。
$ mkdir ruby-chasen ; cd ruby-chasen $ wget http://raa.ruby-lang.org/cache/ruby-chasen/chasen1.6.tar.gz $ tar zxvf chasen1.6.tar.gz $ cd chasen1.6 $ ruby extconf.rb checking for chasen_getopt_argv() in -lchasen... no
うまくいかなそうな予感。
えとブログ https://www.codeblog.org/blog/eto/20060212.html を参考に。
$ sudo apt-get install chasen libchasen-dev chasen-dictutils $ ruby extconf.rb checking for chasen_getopt_argv() in -lchasen... yes
$ make cc -I. -I. -I/usr/lib/ruby/1.8/i486-linux -I. -D_FILE_OFFSET_BITS=64 -fPIC -fno-strict-aliasing -g -g -O2 -fPIC -c chasen.c cc -shared -o chasen.so chasen.o -L. -L/usr/lib -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic -lruby1.8 -lchasen -lpthread -ldl -lcrypt -lm -lc $ sudo make install mkdir -p /usr/local/lib/site_ruby/1.8/i486-linux /usr/bin/install -c -m 0755 chasen.so /usr/local/lib/site_ruby/1.8/i486-linux
うまくいった。
ふたたび script/server
島根県CMSのディレクトリに戻る。
$ ./script/server
Ubuntu の中で Firefox から http://localhost:3000 を開く。今度はトップページが表示される。
よく見ると ERROR ThreadError: not owner というエラーがでているのだが。
ブラウザで操作。右上の「ふりがな」ボタンは動作する。
右上の「よみあげ」ボタンを押すと http://localhost:3000/index.m3u が
Not Found The requested URL /index.m3u was not found on this server.
になる。 public ディレクトリにはそもそも index.html らしきものがない。 rake routes も残念ながら使えない。
このまま doc/INSTALL の指示を無視して development 環境ていじることはできるのだろうか。
トップページの表示
config/routes.rb の最後が
map.connect '*path', :controller => 'visitor', :action => 'view'
になっている。rails のドキュメント http://api.rubyonrails.org/classes/ActionController/Routing.html によれば、
Route globbing Specifying *[string] as part of a rule like: map.connect '*path' , :controller => 'blog' , :action => 'unrecognized?' will glob all remaining parts of the route that were not recognized earlier. The globbed values are in params[:path] as an array of path segments.
とのこと。ということは http://localhost:3000/ は params[:path] に '/' を入れて、 app/controllers/visitor_controller.rb の view メソッドにルーティングされているはず。
当該メソッドを読んでみると、path = request.path となっているが、まあ同じことなのだろう。 path == '/' の場合に起こりそうな処理は、 「Page クラス(モデルだろう)の genre_id が 1 で name が 'index' であるレコードを find する」 である。nil の場合には top (あるいは mobile_top)アクションを render する。
それって、http://localhost:3000/visitor/top ってこと? 404 Not Found になってしまうから、どうやら違うらしい。
ぐぐってみた。
http://akimichi.homeunix.net/hiki/rails/?render
そうか、render :action はいきなり view にいくのか。
app/views/visitor/top.rhtml
があった。しかし、この top.rhtml は、どうも localhost:3000 と内容がちがう。
もしや、migrate したときにデータを入れてくれている?
$ ./script/console Loading development environment. >> Page.find :all => [#<Page:0xb6f8f0c8 @attributes={"name"=>"section", "title"=>"組織別情報", "genre_id"=>"1", "id"=>"4"}>, #<Page:0xb6f8f08c @attributes={"name"=>"page_template1", "title"=>"ページテンプレート1", "genre_id"=>"3", "id"=>"2"}>, #<Page:0xb6f8f050 @attributes={"name"=>"page_template1", "title"=>"ページテンプレート2", "genre_id"=>"3", "id"=>"3"}>, #<Page:0xb6f8f014 @attributes={"name"=>"index", "title"=>"島根県のトップページ", "genre_id"=>"1", "id"=>"1"}>] >> page = Page.find(:first, :include => [:contents], :conditions => ['genre_id = ? and name = ?', 1, 'index']) => #<Page:0xb6f82c38 @attributes={"name"=>"index", "title"=>"島根県のトップページ", "genre_id"=>"1", "id"=>"1"}, @contents=[#<PageContent:0xb6f8242c @attributes={"top_news"=>"2", "admission"=>"3", "comment"=>nil, "section_news"=>"0", "page_id"=>"1", "id"=>"1", "tel"=>nil, "news_title"=>nil, "mobile"=>nil, "begin_date"=>nil, "content"=>"<div id=\"main\"> <h2 class=\"emg\">緊急情報</h2> <%= plugin('emergency') %> <h2 class=\"news\">新着情報</h2> <div class=\"news\"><%= plugin('news', 10) %></div> <div class=\"right\">[<a href=\"/news.1.html\">履歴一覧</a>]</div> </div>", "user_name"=>nil, "last_modified"=>"2007-02-15 12:40:33", "end_date"=>nil, "email"=>nil}>]>
そういうことだったか。
あらためて確認すると db/migrate の 082_load_pages_data.rb と dev_data/{pages,page_contents}.yml のようだ。
directory = File.join(File.dirname(__FILE__), "dev_data" ) Fixtures.create_fixtures(directory, "pages" )
いまどきの作法だと migrate の中でやらないで db:fixtures:load だろう。
そういえば rake default でテストを走らせると
167 tests, 867 assertions, 0 failures, 16 errors rake aborted! Test failures
である。migrate でデータを突っ込んでいて test は通るのだろうか。
unfreeze_rails してみる
rails 1.0 からどこまでバージョンアップできるのだろうか。
$ rake unfreeze_rails
$ ./script/server ./script/../config/boot.rb:16: undefined method `require_gem' for main:Object (NoMethodError) from ./script/server:2:in `require' from ./script/server:2
なおす。
--- a/config/boot.rb +++ b/config/boot.rb @@ -13,7 +13,7 @@ if File.directory?("#{RAILS_ROOT}/vendor/rails") require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer" else require 'rubygems' - require_gem 'rails', '= 1.0' + gem 'rails', '= 1.0' require 'initializer' end
$ ./script/server /usr/local/lib/site_ruby/1.8/rubygems.rb:827:in `report_activate_error': RubyGem version error: rails(2.0.2 not = 1.0) (Gem::LoadError) from /usr/local/lib/site_ruby/1.8/rubygems.rb:261:in `activate' from /usr/local/lib/site_ruby/1.8/rubygems.rb:68:in `gem'
$ sudo gem install rails -v 1.0 ... Successfully installed activesupport-1.2.5 Successfully installed activerecord-1.13.2 Successfully installed actionpack-1.11.2 Successfully installed actionmailer-1.1.5 Successfully installed actionwebservice-1.0.0 Successfully installed rails-1.0.0 6 gems installed ... Installing ri documentation for actionpack-1.11.2... ERROR: While generating documentation for actionpack-1.11.2 ... MESSAGE: Unhandled special: Special: type=17, text="<!-- The header part of this layout -->" ... RDOC args: --ri --op /usr/lib/ruby/gems/1.8/doc/actionpack-1.11.2/ri --quiet lib --title actionpack-1.11.2 Documentation (continuing with the rest of the installation) ...
ri でエラーが得たがインストールは終了。 script/server も無事動き、トップページも表示される。
じゃあ boot.rb が 2.0.2 ではどうか。
gem 'rails', '= 2.0.2'
script/server するがブラウザでエラー。
1.x 系の最終版である rails -v 1.2.6 で試してみたが、やっぱりだめ。
エラーを眺めていて、もしかしたらと思ってやってみた。
--- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -41,7 +41,8 @@ class ApplicationController < ActionController::Base end def rubi_filter - return if @headers['Content-Type'] || !@cookies['ruby'] || @cookies['ruby'].first != 'on' + # @cookies['ruby'].first != 'on' + return if @headers['Content-Type'] || !@cookies['ruby'] || @cookies['ruby'] != 'on' @response.body = RubiAdder.add(@response.body) end
たぶん @cookies[] の結果が array でなくなったのだろう。 これで 1.2.6 対応に(見かけだけは)なった。
なぜ rails をバージョンアップしたかったかというと、
$ script/console >> app => #<ActionController::Integration::Session:0xb6febbe8 @controller=nil, @cookies={}, @headers=nil, @named_routes_configured=true, @remote_addr="127.0.0.1", @host="www.example.com", @path=nil, @response=nil, @https=false, @status=nil, @request=nil, @result=nil, @status_message=nil, @accept="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5">
などが使えた方が嬉しいと思ったからだ。
rake routes も使えるようになった。
$ rake routes /_admin/preview/:id {:action=>"show", :controller=>"visitor"} /_admin/preview_revision/:id {:action=>"show_revision", :controller=>"visitor"} /_admin/word/:action/:id {:controller=>"word"} /_admin/:action/:id {:controller=>"admin"} /_help/:action/:id {:controller=>"help"} /_board/:action/:id {:controller=>"board"} /_board_comment/:action/:id {:controller=>"board_comment"} /board/:id/:page {:action=>"view", :controller=>"board_comment"} /_enquete/:action/:id {:controller=>"enquete"} /_statistics/:action/:id {:controller=>"statistics"} /_advertisement/:action/:id {:controller=>"advertisement"} /_mailmagazine/:action/:id {:controller=>"mailmagazine"} /_site/:action {:controller=>"site"} /_web_monitor/:action/:id {:controller=>"web_monitor"} /_qr/:path {:action=>"qrcode", :controller=>"visitor"} /:path {:action=>"view", :controller=>"visitor"}
cron による処理
話を戻して、読み上げ機能の動作を解明したい。
あらためて doc/INSTALL を読む。
「exportの設定」「cronの設定」によると。
var/share/cms に展開されたプログラム一式 (今回の作業ではそのように展開していないが) で tool/export を書き換えて、 「公開サーバのドメイン」 「公開サーバにrsyncするユーザ」 を指定することになっている。
crontab.example を見る。
# htmlページの公開サーバへrsyncするスクリプトの実行スケジュール * * * * * if [ -e '/var/share/cms/do_export' ]; then nice /var/share/cms/tool/export; fi # 音声ファイルを作成するスクリプトの実行スケジュール * * * * * if [ -e '/var/share/cms/do_export' ]; then nice /var/share/cms/tool/export_mp3; fi
tool/export は VoiceSynthesis が使われている(唯一の)場所だ。
tool/export_mp3 は tool/export を load している。 Job.next_mp3 がないなあ、と思って探す。
$ find . | xargs grep next_mp3 ./tool/export_mp3: while job = Job.next_mp3 ./app/models/job.rb: def self.next_mp3
あった。
def self.next_mp3 self.find(:first, :conditions => ['(datetime <= ? or datetime is null) and action = ?', Time.now, 'create_mp3'], :order => 'id') end
あらためて toos/export を探すと、こんな感じで生成されている。
Job.create(:action => 'create_mp3', :arg1 => arg, :arg2 => tmp_id, :datetime => Time.now)
Job を生成して DB に入れておき、export の最後にある
while job = Job.next @exporter.run(job) end
で実行している。run は CMSExport のメソッドである。 export_mp3 の場合は Job.next ではなく Job.next_mp3 が使われる。 Job の処理は奥深そうだ。
ここまでのまとめ
非常に偏った視点でこのソフトウェアを概観してみた。 島根県公式サイトとしての外部仕様を満たすための苦労(アドホックな部分?)が散見されるが、 そもそもこういう「斜め読み」ができるのは Rails アプリであるおかげだろう。
「漢字に対するルビの自動生成」は JavaScript で実現されている。 「聴覚スタイルシート」は public/stylesheets/aural.css として提供されている。
音声合成だけでなく、このような 「アクセシブルなWebサイト」 を実現する機能がいろいろ盛り込まれていることはやはり興味深い。
これらの技術が独立したパーツとして生かされることで、 高度なWebアクセシビリティ技術が幅広く普及することを望む。