QuickWikiまだやってる

listまでやってみた。

ここまでやって感じることは、チュートリアル自体の題材や説明の仕方は、Djangoのチュートリアルの方がわかりやすいな、ということ。QuickWikiは確かにエッセンスが凝縮されてるのでその後の応用の際に参考になりそうなんですが、最初のチュートリアルとしてはやはりemp表のようなオーソドックスなものの方がわかりやすいと思います。でもそれは、もしかするとDjangoPylonsの思想の違いなのかもしれない。Pylonsはより柔軟なフレームワークを目指している関係上、題材も欲張っている、というところか。

そういえばDjangoチュートリアルを見直してみて思ったんだすが、Djangoの場合サイトを作ってその中にアプリケーションを作るんですが、Pylonsの場合はおもむろにアプリケーションを作るとその中にサイト情報が書かれています。これはチュートリアルの記述がたまたまそうなのか、設計思想の違いなのかちょっと気になるところです。

それから、index()やlist()、detail()などのメソッドDjangoではビューとして扱われているのにPylonsではコントローラとして扱われている。たしかに返す値がDjangoの場合はHttpResponse、Pylonsの場合はRenderというところからして違うのでどちらも理屈としてはあっているんだろうけど、実質的には同じようなソースになるわけで、両方使ってると用語に関しては混乱しそう。

QuickWikiやってる途中

引き続きQuickWikiチュートリアルをやっています。
もともとの趣旨からはかなり離れたところにいるわけですが、最終的には戻ってきますよ。

QuickWikiに関しては、すべてのコードを理解しながらやろうと思ったんですが、ちょっと時間がかかりすぎそうなのでざっくり終わらせてから理解を深めたいと思います。できれば最終的にはQuickWiki詳解みたいなまとめを書いて自分なりの理解度を確認したいと思います。

以下、前回の疑問点などを調べてみたメモ

  • PasteはWSGI用のWebアプリ作成支援ツール見たいな感じのもの。
  • そもそもWSGIを知らなかったんだけど、WSGIというのはPythonでWebアプリを作るための規格・・・というより規約で、これに準拠(という言葉が適当かどうかはわからないけど)してなくてもWebアプリは作れるけど準拠しておけば他のツールやライブラリとの連携が楽になる、というもの。Webサーバ-WSGI-(フレームワーク)-Webアプリというレイヤーになっていて、直接WSGIに従ってゴリゴリとアプリを作ってもいいし、WSGIフレームワークを使ってアプリを使ってもいい。いずれにしてもWSGIにのっとって作られたアプリであればPasteのようなツールが利用できるし、Webサーバを置き換えるとかどこかのライブラリを置き換える、といった場合の互換性がある程度確保されていることになる。
  • Javaで言えば「JavaでWebサーバ作るときには大体最初は似たようなこと書くんだからそこは規格は統一しましょう」ということでServletが作られたような感じ。Servlet(Tomcatとか)を直接使ってアプリ作ってもいいし、フレームワーク(Strutsとか)を使ってもいい。これも大体同じ。ただ、Servletという規格に対するTomcatという実装、のようにWSGIが仕様で実装がいくつもあるのかとかそういう点はよくわからなくて、どうやらServletと違ってWSGIというのはクラスじゃなくてインターフェイスなんじゃないかと想像。
  • Pylonsは最初からWSGIに準拠するつもりで作られたフレームワークなのでWSGIの互換性は非常に高く、その結果Pasteを使いまくっている。WSGI準拠フレームワークのリファレンスを狙ってるのか!? ちなみに他のDjangoZopeは元々独自に作られたフレームワークだけど、最近のバージョンではWSGI互換になっている。

こんな感じかな。違ってたらどなたかツッコミよろしく。

以下、新たなメモ

  • SQLAlchemyのマッピング定義はやってみると結構煩雑。RoRDjangoの内蔵ORMよりはJavaHibernateに近い。XMLの代わりにPythonで書いてるだけ、みたいな。
  • そこで調べてみた。やはりSQLAlchemyはちょっと面倒くさいと思う人が多いようで、SQLAlchemyをさらにラッピングして簡単にしたElixirとか、SQLAlchemyオフィシャル?で同様の機能を実装したdeclarativeプラグインというのがある。だったらSQLAlchemy使わずにSQLObjectでいいじゃん、という話もある。その辺の違いなどはまだ使ってないので不明。そもそもORM自体が苦手というか実用性をあまり評価してない(SQL書きゃいいんじゃないの?みたいなノリ)ので、もちょっと調べてみる必要がありそう。

Pylonsでいこう

またまた久々の更新です。
前回の日記に書いた通り(最終的にどうなるか未定ですが)、Webベースのソースも書いてみようということで、その辺の調査をやっています。

当初はフレームワークDjangoを使おうかと思っていたんですが、どうもRuby on Railsと同じく自由度が低いというか「レールの上を進みなさい」という感じがしてちょっと馴染めませんでした。そういうわけで最近はPylonsを試しています。PylonsDjangoよりはやや自由度が高く、逆に言うとコーディング量がちょっとだけ多い感じです。これなら「レールの上を進んだ方がいいですよ」くらいにはなっているのではないかと。

オフィシャルのここを順にやっていて、現在QuickWikiチュートリアルの途中です。

以下、メモ的なもの。

  • sessionはわかる。gオブジェクトもわかる。でも、cオブジェクトは何? リクエストごとに初期化されるってことは、Servletでいうrequest.setParameter()みたいに使うものじゃないかと想像。でも、requestオブジェクトは別にあってrequest.paramsなんていうのも使える。もしかするとrequest.paramsはフォーム値をActionに返すためのStrutsで言うDynaActionFormみたいなもので汎用的には使えないのか? もう少し読み進むとわかるのかな。
  • Pasteが何なのかいまいちわからん。Pylonsプロジェクトのものでないのはわかったけど、どのへんがPaste一般でどこまでがPylons固有なのかが謎。Pasteのサイトに行ってもますますわからん。とりあえず-hを読んでなんとなく「paster create」まではPasteが用意しているもので、PylonsはPasteが作るファイルのテンプレートをあらかじめ用意している、みたいな感じか? 「paster create -t 」の-tはテンプレート。paster createに関してはまだ-tと-hしか使ってない。

サブプロジェクトIWAISOME

しばらくぶりの更新です。が、ソースは書いてませんw

新しいサブプロジェクトIWAISOMEを構想中です。

ここまで書いてきてAOISORAとして公開しているものは、いわゆる従来のツリー型アウトラインプロセッサで、巷にいくらでもあふれているものです。これは誤解を恐れずに言えば、トップダウン的に全体像を考えながら徐々に掘り下げて文書を書いていくタイプのソフトウェアです。それに対して今後AOISOMEで作っていこうと思っているのはチップ(仮称)という素材をたくさんストックしていき、それをノード(仮称)という単位にまとめ、ノード同士は有機的に結合しあいリゾーム構造となる、そしてそのリゾームのなかからどれかのノードを中心に芋づる式に引っ張ってきてツリー構造として再構成する、というボトムアップ的なアプローチで文書を作成するリゾームプロセッサ(謎)です。

そしてIWAISOMEでやろうとしているのは、それらトップダウンvsボトムアップという理想論はおいといて、「今ほしいのはどんなソフト?」という自分の必要性から生まれたアイデアです。前回の日記にも書きましたが、今自分で求めているのは仕様書やマニュアルを書くためのソフトです。もっと言えば、開発者向け仕様書をアップデートする作業とユーザ向けマニュアルをアップデートする作業を一括で行えるようなシステム屋向けドキュメント作成支援ソフト、です。

最近はUMLのクラス図なんかをソースから自動的に作り出すツールなどはありますが、僕はああいうのは求めてません。ソースから導き出される情報は最悪ソースを読めばわかるし技術者しか読まないのでそんなに重要ではありません。重要なのはユーザとのやりとりが開発にスムーズに反映され、開発の結果が効率よくユーザの利用につながるためのドキュメント作成です。開発者向けの画面定義書とユーザ向けの機能リファレンスが開発と同時にアップデートされていき、できれば進捗管理(Tracとかsubversionとか)とも連携できる、そんなイメージです。

そしてそういうった仕様書/マニュアルに特化した文書作成ツール「IWAISOME」もある程度形になった時点で徐々に汎化されていき、トップダウン的なツール「AOISORA」とボトムアップ的なツール「AOISOME」と最終的には統合される形で完全体「AOISO」ができていくような、そういう壮大な構想です。

「ユーザ向けドキュメントなんてワードとかOOoで書けばいいじゃん!」という人も多いと思いますが、やはり細かなメンテが大変です。仕様書スクリーンショットを張り替えたらマニュアルのスクリーンショットも最新になっているような、複数の開発者が同じドキュメントのそれぞれの担当セクションを同時に更新できるような、そういうのがほしいな〜、と思っているので作ります。探したらそういうソフトがすでにあるかもしれないけど、完成目標が別のところにあると思うので、いずれにしても作ります。

多分Webベースだな〜。Djangoかな〜。

久々コミットと近況

rev.51でSQL文とかコミットしました。・・・と言っても実はコミットし忘れてた分なので、2週間くらい前のソースです。

今漠然と考えていること。

  • テキストオンリーじゃダメだ。マニュアルやまとまった文章を書くには図や表も扱わざるをえない。そう。最低でも画像を文書中に埋め込めるようにしよう。対応フォーマットはjpg、pngsvg。あとは気が向いたらbmpgif・・。動画はいらんだろう。表はどうしよう?
  • ノード=タイトル+本文、という考えを捨てよう。タイトルがないノードがあっても良いはず。
  • そもそも最小単位がノードじゃダメなんじゃないだろうか。画像を含める場合、ノードの中に画像の前の文、画像、画像の後の文の3つの要素が最低必要になるはず。画像が2つあれば5つの要素。タイトルも要素だとすればそれプラス1。この要素をなんと呼ぼう。とりあえず今のところチップとしておく。チップにはタイトルチップ、テキストチップ、画像チップなどがあり、複数のチップで1つのノードを構成する。標準的なツリー型アウトラインプロセッサはノードがタイトルチップ1+テキストチップ1という構成に肯定されている、という考え方。しかし、だとすると段落はどう考える? 1テキストチップ=1段落?いやいやそれは面倒だ。10段落のテキストを1チップで扱っても特に問題ないだろう。どこでわけるかはユーザ判断でいい?
  • 思いつきメモはツリー構造をとらない。練られたテキストはツリー構造をとる。アウトラインプロセッサの役割は非ツリー情報のツリー化。非ツリー情報を非ツリーのまま扱うメモデータベース機能は必要?不要?>必要であることを想定して作りつつあるけどね。

続・SQLiteのトリガとか

先日タイムスタンプのためのAFTER INSERTトリガを書いたのですが、更新時のタイムスタンプ更新はどうするんだろう? と思い、今回ためしにAFTER UPDATEトリガで書いてみました。なお、pythonソース内で読みやすいようにSQLは大文字で統一することにしました。

CREATE TRIGGER T_NODE_AFT_UPD                       
AFTER UPDATE ON T_NODE                              
BEGIN                                               
  UPDATE T_NODE                                     
  SET UPDATE_TIMESTAMP=DATETIME('NOW', 'LOCALTIME') 
  WHERE NODE_ID=NEW.NODE_ID;                        
END                                                 

結論から言うと、これでうまくいきました。常識的に考えると「AFTER UPDATEトリガで自分のテーブルにUPDATE文発行すると無限ループ」と思ってしまいますが、その辺はうまくできているということでしょうか。たしかFirebirdでこれやるとエラーだったと思います。やはりBEFORE UPDATEでNEW.に代入できればそれが一番スマートだと思いますが、このようにAFTER UPDATEで対処できるのならまぁいいでしょう。以前トリガのない某DBを使ったときには独自の変なタイムスタンプ機能を使ったりしていて気持ち悪かったのですが、SQLiteはその点素直でいいと思います。

ところで、INSERT時のタイムスタンプはトリガじゃなくてDEFAULTでいいんじゃないかと思って以下のようにやってみました。

 /*NG*/
 CREATE TABLE ....
   CREATE_TIMESTAMP TIMESTAMP DEFAULT DATETIME('NOW', 'LOCALTIME') NOT NULL

しかし、CREATE TABLE文に関数を入れるのはダメなようです。実際には次のようにやるようです。

 /*OK*/
 CREATE TABLE ....
   CREATE_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL

ですが、これでやるとLOCALTIMEではなくUTC標準時刻が入ってしまいます。以下のようにできればいいんですがこれもムリ。

 /*NG*/
 CREATE TABLE ....
   CREATE_TIMESTAMP TIMESTAMP DEFAULT CURRENT_TIMESTAMP LOCALTIME NOT NULL

内部的にはUTCに統一するという手もあるんですが、それはそれで面倒なのでDEFAULTはあきらめトリガでやることにします。

今後のAOISOME

Rev.48で一旦AOISOMEをリセットしました。現在AOISOME=AOISORA=0.1.0です。
AOISOMEはこれから新境地へ向かいます。これからやることは正直自分自身にもよくわかっていませんw。これまでのアウトラインプロセッサにはなかった新しいアイデアを試してみるつもりです。今考えているのはこんな感じです。

* ノードは並列。つまりツリーで管理されていない。
* 一つのノードを複数のツリーに属させることができる。
* 文字情報以外も扱える。
* ネットワーク上の複数のパソコンで複数のユーザーが同じ文書を編集可能。
* AOISOがインストールされていないパソコンでも編集可能。

後半は個人で文書を書いているときにはあまり重要じゃないと思いますが、こういうことができると面白いことができそうな気がするので、ものはためしでやってみたいと思います。