Puroland Greetingの設計と実装
いつの間にかオープンソースにしていたPuroland Greetingのシステムについて解説します。
構成
本システムは、クローラとWebサーバの2つのプログラムから構成されています。クローラは、サンリオピューロランドの公式サイトからグリーティング情報を取得し、データベースに格納します。Webサーバは、ユーザからのリクエストに応じてデータベース内の情報を表示します。
テーブル構成
データベースのテーブル構成は以下のER図のようになっています。なお、ここでは本質的ではないいくつかのカラムは省略しています。
schedules
は、複数回のグリーティングを束ねた1日のスケジュールを表現するためのテーブルです。1行が1日に対応しています。
greetings
は、グリーティングを表現するテーブルです。本システムでは、開始時刻、終了時刻、場所の3要素が一致する複数のキャラクターの登場を1つのグリーティングとして扱います。Webページの下図のような枠1つが1行に対応すると考えるとわかりやすいかもしれません。
appearances
は、greetings
とcharacters
を結ぶための中間テーブルで、キャラクターの登場を表現しています。
characters
、costumes
、places
は、それぞれキャラクター、衣装、場所を表現するテーブルです。キャラクター、場所については特に説明は不要かと思います。衣装というのは、キャラクター名の後ろに括弧書きで記述された内容 (ハロウィンなど) のことを意味しています。
クロール
解説は必要ないと思われるので省略。ちなみに、クローラのUser-AgentはiPhone (Ruby; http://greeting.sucretown.net/)
です。
情報の表示
本システムで一番使われている /schedule/yyyy/mm/dd/
のタイムテーブル表示について解説します。といっても、本システムの要であるレスポンシブデザインはBootstrapが実現してくれているものなので、ここではHTMLの組み立て方とJavaScriptの処理概要について述べます。
HTMLの組み立て
HTML生成の流れは以下のとおりです。これはあくまで概念的なものなので、実際の処理順序とは異なります。
- 対象となる日のすべての
greeting
を取り出す - 開始時刻と終了時刻の組でグルーピングを行い、
greeting-group
を作る - 各
greeting-group
を開催中 (開始時刻が現在時刻以降かつ終了時刻が現在時刻以前)、開始前 (開始時刻が現在時刻より後)、終了 (終了時刻が現在時刻より前) の3種類のgreeting-category
に分類する - 各
greeting-category
内のgreeting-group
を終了時刻順で並び替える (終了時刻が同じ場合は開始時刻順) - 各
greeting-category
およびgreeting-group
について順にHMTLを生成していく
最終的に出力されるHTMLのグリーティング情報部分は以下の図のような構造です。図中の緑の部分は最終的なレンダリング結果として描画される部分で、破線部分は実際には表示されません。
PCだと同じ時間のグリーティングが横に並び、スマホでは縦に並ぶ機能は、BootstrapのGrid systemによって実現しています。
HTML (の元になるHamlテンプレート) はviews
ディレクトリ、CSS (の元になるSCSS) はassets/stylesheets
ディレクトリにあります。Hamlで書かれているので理解しづらいかもしれませんが、タグで囲む代わりにインデントで階層構造を表現しているだけで、複雑なものではありません。上の図や実際に動いているシステムのHTMLと見比べると若干わかりやくなると思います。
JavaScript
本システムのJavaScriptは、主にgreeting-category
の更新を行っています。具体的には、毎分各greeting-category
の開始時刻と終了時刻 (それぞれdata-start-at
属性とdata-end-at
属性) をチェックし、現状から変化する場合には適切なgreeting-category
内に配置し直します。この処理はassets/javascripts/greetings.js
に記述されています。