2007/09/09
■[Programming]LinearNote: Ruby on Railsで動くWikiのようなblogのようなメモ帳
この夏Ruby on Railsの勉強のために作ってたアプリケーションを、RubyForgeに登録しました。
RubyForge: LinearNote: Project Info
http://rubyforge.org/projects/linearnote/
ソースコードの量もまだそれほど多くない(というかかなり少ない)ので、Ruby on Railsの勉強にも役立つかもしれません。もしよかったらご覧ください。
■ これは何?
個人的なメモの記録を目的とした、メモ帳アプリケーションです。メモ帳アプリケーションはデスクトップアプリとしてもWebアプリとしても既に色々ありますけど*1、LinearNoteは特に以下の用途に特化しています。
- 普段は、気軽にメモを溜めたい(手元のPCにテキストファイルを書きためるように)
- でも、時々はメモの一部を他の人に公開したい。またはそのメモをベースにWikiのページを作りたい
利用イメージとしては、自宅または職場に1つLinearNoteのサーバを立てて、そこにありとあらゆるメモを残していくような感じです。
書き込まれたメモはデフォルトでは非公開状態になるので、普通に使う分にはWindowsの「メモ帳」でテキストファイルを作りまくるのと同じように気軽に書けます。それに加えて、適当に書いたメモをあとで他の人に公開したくなったときに、整形したりいくつかのメモを集めて1つにしたりするところで、LinearNote特有の機能が色々とフォローするわけです。
■ 主な機能とスクリーンショット
現在のバージョン(LinearNote 0.1.0)で実装している主な機能をご紹介します。
1. 複数のノートブックをホスト
LinearNoteにユーザ登録を行うと、誰でもノートブック(1つのWikiに相当するもの)を作成できるようになります。ユーザ登録画面はこんな感じ。
ユーザ登録すると、自分のノートブックを作れるようになります。
ノートブックの種類は、以下の4種類から選べます……が、Groupの機能は未実装です。すいません。
- Personal(所有者だけが書き込み可能)
- Group(許可されたメンバだけが書き込み可能)
- Public(登録ユーザ全員が書き込み可能)
- Exposed(どんなユーザも書き込み可能)
2. プレーンテキストかPukiWiki形式でメモ
作成したノートブックでメニューの「New Note」をクリックすると、メモ(LinearNoteでは「ノート」と呼んでる)の作成画面に入ります。
ノートを記入すると、画面下のプレビューが自動的に更新されます。メモのスタイルは、PlainスタイルかPukiWikiスタイルから選択できます(デフォルトのPlainスタイルを選んだ場合は、ノートが等幅フォントで表示されます)。
PukiWikiパーサには、Rubyist Magazine出張版に載っている添削後のPukipa(MITライセンス)を使わせていただきました。作者のgorouさん、添削者の青木さん、ありがとうございます。
3. メモの表示方法をカスタマイズ
これがLinearNoteの目玉機能です。他のアプリにあってもおかしくないけど、僕は見たことないので今回作ってみました。
何も考えずに適当にメモを残していると、いざ他の人にも見せようと思ったときに再編集が面倒です。そこで、その再編集を助けるために、LinearNoteは「スマートインポート」機能を備えています。
スマートインポートとは、簡単に言うとiTunesのスマートプレイリストと同じような機能です。iTunesでは、「ジャンルがRockの曲」とか「アーティスト名がthe pillows」という条件付きのプレイリスト(スマートプレイリスト)を作ると、その後曲が増えたり減ったりしても、そのプレイリストの中身が自動的に更新されます*2。参考までに、iTunesのスマートプレイリストの設定画面はこんな感じです(↓)。
LinearNoteのスマートインポートでも、あるノートの中に他のノートをインポートするために、「タグがp2p」とか「タイトルか本文にRuby on RailsかRoRという文字列が入っている」という条件を付けることができます。スマートインポートの設定画面は次のようになります。
スマートインポートを設定すると、ノートの下に、条件にマッチするノートの一覧が表示されます(ノートの増減に合わせて自動更新)。加えて、このノートの一覧のRSS(図の赤丸部分)を、ノートブックの最終更新一覧のRSSとは別に配信しており、ノートブックの特定の部分だけをRSSリーダで購読できるようになっています。
これをどう使うかというと……例えば、ノートブックのトップページで「タグがdiaryのノートを読み込む」というスマートインポートを設定して、公開したいノートにだけdiaryタグを付けるようにすると、トップページだけ見ると普通のブログのように見えます。RSSも出ますしね。
ちなみに、このインポート機能は自分のノートブックに対してでなく、他の人のノートブックや、全てのノートブックに対しても実行できるので、この機能自体をRSSリーダのように使う事も可能です。
■ 使ってみるには
LinearNoteの動作例
すいません。動作例はいまのところ公開してないです。さくらのレンタルサーバじゃちょっと動きそうにないので、今後の予定も未定です……。
インストール方法
RubyForgeからソースコードをダウンロードして、普通のRuby on Railsアプリケーションと同じようにすれば動作します(詳しい手順はまた後ほど)。企業内でこっそりいじるような利用法もサポートするため、ソースコードはMITライセンスで公開しました。
RubyForge: LinearNote: Project Info
http://rubyforge.org/projects/linearnote/
Railsアプリのgemの作り方が分からなったので、まだgemファイルはありません。
Ruby全般だとnewgemやHoeが使えそうというのは調べたんですけど、newgemはRailsとscriptファイルの名前が衝突してるし、Hoeは「binディレクトリが無い」とエラーを出すし、一体どうしたらいいのか分からないんですよね……。
動作環境
開発環境は以下の通り(要するにInstantRails 1.7)です。が、特殊な機能は使ってないので多少違う動作環境でもおそらく動くと思います。
- Windows XP SP2
- Ruby 1.8.6
- Rails 1.2.3
- MySQL Community Server 5.0.27
CentOSで動作することは、ちょっとだけ確認しました。db/migrate/001_setup_database.rb の中身をいじれば、MySQL以外のデータベースでも動くはずです。多分。
■ 今後のToDo
- ノートブック間でのノートの移動、コピー
- ユーザ同士のコミュニケーション機能(コメント機能か何か)
- 管理者向けの機能
- ノートの自動保存
- ノートのリビジョン管理
- インターフェイスの改善
■ ご意見ご感想
お待ちしています。コメント欄か、yoshizawa at muziyoshiz.jpまでお願いします。
*1 デスクトップアプリケーションではhowmや紙copi、WebアプリケーションではRandomNoteやTiddlyWikiなどなど。
*2 「ライブアップデート」のチェックを入れている場合に限りますが、普通このチェック外しませんよね??
最近、MVCにきっちり分かれてるコードばかり読んでたので、これは読むのがつらい。 ある程度class,functionの読み解きは出来たけど、なんかやる気が出ない。 Rails2.0の勉強も兼ねて、備忘録に特化したシステムを作っちゃおうかな。 単純にタグ範囲でランダム表示したいだけ
また、この日記に無関係と判断したコメント及びトラックバックは削除する可能性があります。ご了承ください。








muziyoshiz.jpまでどうぞ。


Award on Rails コンテストに出してみませんか?
コメントありがとうございます。<br>ただ、うーん……個人的にはまだイマイチだと思うので、今回は遠慮しておきます。
初めまして、北村と申します。<br>面白そうなので入れてみました。<br>WindowsXP Pro,ruby1-8-6,Rails1-2-3,mongrel_cluster、SQlite3で動かしています。<br>まだRailsを勉強し始めたばかりですので、少しずつソースを勉強していきたいと思います。<br><br>Apacheでリバースプロキシを設定して動かそうとしたときに気づいた点が。<br>LinearNoteを<br>http://localhost:3000/linearnote/<br>のようにルート以外で動かしてメモを作ると、リンクが崩れました。<br>自分で問題を解決しようとしましたが、まだ勉強中の為ご報告出来ません、申し訳ありません。
不具合のご報告ありがとうございます。<br>確かに、そういう状況ではまだテストしてみていませんでした……。私の方でも、リバースプロキシを設定して試してみます。
とりあえずの対策としては、app/controllers/note_controller.rbの299行目の<br><br> if request.request_uri =~ /^\/[^\/]+\/(.+)$/<br><br>を<br><br> if request.request_uri =~ /\/#{Regexp.new(params[:notebook])}\/(.+)$/<br><br>に変えれば動くと思います(僕の手元ではとりあえず問題ありませんでした)。<br><br>この部分は、リクエストURIを直接パースして(routes.rbを使わずに)<br>ノートの名前を取り出している部分です。<br><br>かなり馬鹿なことをしていると自分でも思うんですけど……。<br>こうしないと、Railsのバグなのか仕様なのか<br>ノートの名前に含まれている+(プラス)が、params[:note]の中では<br>スペースに変換されてしまってうまく動作しないので、仕方なくこうしてます。<br>(このあたりはそのうち日記に書こうと思ってたんですが、すっかり忘れてました)
即の対応ありがとうございます。<br>こちらでも正しく動きました。<br><br>params経由でそんな問題があるとは知りませんでした。<br>馬鹿な事とかおっしゃってますが、task*padもどきを練習で作った程度の私には、このようなアプリを作成されてる時点で眩しい……
ためしにrails2.0で動かしてみたら、notebook_url(notebook_action_url)周りの処理でエラーを吐いてしまい、動作しませんでした。<br>どうやらaction_controller/routing.rbの挙動が少々変化しているみたいです。<br>時間が無くて、どこがおかしいのかまでは追うことは出来なかったです。。。
お試しありがとうございます。うーん、Rails 2.0では動きませんでしたか……。<br><br>rails 2.0でrouting.rbの挙動が変わった影響という話は聞いてましたけど、<br>動かなくなるほどの影響があったとは。。冬休みあたりに僕もrails 2.0試してみます。ちなみに、どんなエラーでしたか?
長文で失礼します。<br><br>以下のようなエラーがまず出ています。<br>どうやらnotebook_urlを正常に処理できていないみたいですね。<br>私はrouting.rbを追っている途中で挫折しました。<br>他にもredirect_to_urlやacts_as_list等が影響を受けているところまでは追ってます。<br><br><br>3: <% if @notebook.authorize?(current_user) -%><br>4: <div class="note-menu"><br>5: <ul><br>6: <li><%= link_to 'Edit', notebook_url(:action => 'new_note', :notebook => @notebook, :title => title) %></li><br>7: </ul><br>8: </div><br>9: <% end -%><br><br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_controller/routing.rb:1412:in `raise_named_route_error'<br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_controller/routing.rb:1376:in `generate'<br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_controller/url_rewriter.rb:124:in `rewrite_path'<br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_controller/url_rewriter.rb:103:in `rewrite_url'<br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_controller/url_rewriter.rb:81:in `rewrite'<br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_controller/base.rb:616:in `url_for'<br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_view/helpers/url_helper.rb:71:in `send'<br> /var/lib/gems/1.8/gems/actionpack-2.0.1/lib/action_view/helpers/url_helper.rb:71:in `url_for'<br> (eval):15:in `notebook_index_url'<br> lib/linearnote/routes.rb
ありがとうございます。確かに、notebook_urlのURL生成で失敗してますね。<br>あとで僕もソースコード読んで調べてみます。<br><br>>他にもredirect_to_urlやacts_as_list等が影響を受けているところまでは追ってます。 <br>うーん、僕が予想してた以上にあちこちコケてるっぽいですね。<br>Rails 2.0への移行はけっこう手間取りそうだなあ……。
routes.rb周りは私もこれまであまり触れてこなかった領域なので、あまりお役に立てませんが、必要なものがあったら言ってください。<br>後、使ってみてタグ機能周りが個人的に欲しかったので個別に実装してみました。<br>http://linearnote.udcp.net/u-ichi<br>かなり無理やりな実装ですが、あると結構便利です。
おお、すごい。色々いじってますね。<br>ランダム表示って、tumblr由来の機能なのかな……(実は使った事ない)。<br>なんか、本体で直した方がよさそうな機能とか、<br>反映して欲しいコードがあったらぜひ教えてください。できるだけ直しますので。<br><br><br>あと、これをみて思い出したのですが<br>タグ機能周りで、もし、複数のタグを使ったAND/OR検索が必要でしたら、<br>一応models/note.rbに実装してあるので使ってみてください。<br>(どういうインターフェイスにしようか悩んで、結局隠し機能なままだったんでした……)
>ランダム表示って、tumblr由来の機能なのかな……(実は使った事ない)。 <br>tumblrには無いけど、使っていたら欲しくなったので作った次第です。<br>メモってたらすごく欲しくなったので、機能的に出来るやつは無いかなと探し回ってたどり着いたって感じですね。<br>(メモっておいた内容を定着化のために何度も見るという事をやりたかったので・・・)<br><br>>なんか、本体で直した方がよさそうな機能とか、<br>>反映して欲しいコードがあったらぜひ教えてください。できるだけ直しますので。 <br>タグ周りの機能がまだ弱いかなと思うので、この辺は是非本家の方にも実装してもらえるとすごく嬉しいです。<br>コード内容的には非常に洗練されていて非常に勉強になってるので、今のところ特に突っ込むところはないです。<br>あまり人の書いたコードを読みなれていないので、読み解くのには苦労しましたが。。。