2009-03-19
Werkzeugチュートリアル惰訳
データベースにURLを格納するTinyURLクローンを作成する
Werkzeug0.2チュートリアルへようこそ。
このライブラリは、データベースレイヤのためのSQLAlchemyを利用するアプリケーション、
テンプレートにjinjaを利用するアプリケーション、そして、もちろんWSGIレイヤのために
werkzeugを利用するアプリケーションで使用されることを想定しています。
私たちがチュートリアルのアプリケーション用にこれらのライブラリを決めた理由は、
Djangoが過去にした設計決定のうちのいくつかに固執したいということです。
そのうちの1つは、アクションメソッドを備えたコントローラー・クラスの代わりに
ビューファンクションを使用することです。それはRailsとPylonsにおいても共通の思想です。
他には、デザイナーにやさしいテンプレートを提供していることです。
Werkzeugのexample folderhttp://dev.pocoo.org/projects/werkzeug/browser/examplesには
あなたが好きなときに参照できる他のテンプレートエンジンを利用した一組のアプリケーションが
含まれています。そしてそこには、そのアプリケーションのソースコードもあります。
チュートリアルを実行するのには、まず、jinjaとSQLAlchemyを導入してください。
あなたがeasy_insatllを実行できる環境であるならば、以下のようにします。
sudo easy_install Jinja
sudo easy_insatll SQLAlchemy
私の環境では、以下のような実行結果となりました。
C:\>easy_install SQLAlchemy
Searching for SQLAlchemy
Best match: sqlalchemy 0.5.2
Processing sqlalchemy-0.5.2-py2.5.egg
Removing sqlalchemy 0.3.10 from easy-install.pth file
Adding sqlalchemy 0.5.2 to easy-install.pth file
Using c:\python25\lib\site-packages\sqlalchemy-0.5.2-py2.5.egg
Processing dependencies for SQLAlchemy
Finished processing dependencies for SQLAlchemy
C:\>easy_install Jinja
Searching for Jinja
Reading http://pypi.python.org/simple/Jinja/
Reading http://wsgiarea.pocoo.org/jinja/
Reading http://jinja.pocoo.org/
Best match: Jinja 1.2
Downloading http://pypi.python.org/packages/2.5/J/Jinja/Jinja-1.2-py2.5-win32.egg#md5=27b0804a126c2c0ebd4a9dacffb9dcbb
Processing Jinja-1.2-py2.5-win32.egg
creating c:\python25\lib\site-packages\Jinja-1.2-py2.5-win32.egg
Extracting Jinja-1.2-py2.5-win32.egg to c:\python25\lib\site-packages
Adding Jinja 1.2 to easy-install.pth file
Installed c:\python25\lib\site-packages\jinja-1.2-py2.5-win32.egg
Processing dependencies for Jinja
Finished processing dependencies for Jinja
もしあなたがWindows上でチュートリアルを試そうとしているなら、"sudo"ははずして実行してください。
(setuptoolsのインストールはわすれずに)
OS Xなら、portから、Linuxなら、package managerでpython-jinjaとpython-sqlalchemyとして実行してください。
Part0:フォルダ構成
チュートリアルを開始する前に、Werkzeugアプリケーションとテンプレート、静的ファイルのためのフォルダを
作成する必要があります。チュートリアルアプリケーションは、チビ"shorty"と呼ばれます。
また、私たちが使用する最初のディレクトリ階層は以下のように見えます。
manage.py
shorty/
__init__.py
templates/
static/
__init__.pyとmanage.pyファイルは、当分の間空ファイルです。
最初に作成したshortyフォルダはpython packageです。二つ目に作成したものは管理ユーティリティを
保持するためのものです。
Part1:The WSGI Application - PEP333 Python Web Server Gateway Interface v1.0
Djangoや他のフレームワークとは違い、WerkzeugはダイレクトにWSGIレイヤにオペレーションします。
デベロッパのためにセントラルWSGIアプリケーションを実行するファンシーな魔法はありません。
あなたが、最初に書くのは、基底WSGIアプリケーションオブジェクト実装です。それは、関数にも
callable classにもなりえるでしょう。
callable classには、関数にはないアドバンテージがあります。
一つは、callable classにいくつかのコンフィグパラメーターを渡すことができます。
更に、インラインのWSGIミドルウェアを使用することもできます。
インラインWSGIミドルウェアは、基本的には私たちのアプリケーションオブジェクトの”内部に”適用できるミドルウェアです。
これは、アプリケーション (session middlewares, メディアファイルをサーブするような etc.)にとって
不可欠なミドルウェアに対する良い考えです。
以下に shorty/application.pyファイルというWSGIアプリケーションを実装するための最初のコードを示します。
#!/usr/bin/env python # -*- coding: cp932 -*- # via. Werkzeug Tutorial Part 1: The WSGI Application # %PYTHONPATH%/werkzeug-0.4.1-py2.5.egg/docs/tutorial.html from sqlalchemy import create_engine from werkzeug import Request, ClosingIterator from werkzeug.exceptions import HTTPException from shorty.utils import session, metadata, local, local_manager, url_map from shorty import views import shorty.models class Shorty (object): def __init__(self,db_uri): local.appliaction = self sefl.database_engine = create_engine(db_uri, convert_unicode=True) def init_database(self): metadata.create_all(self.database_engine) def __call__(self, environ, start_response): local.application = self request = Request(environ) local.url_adapter = adapter = url_map.bind_to_environ(environ) try: endpoint, values = adapter.match() handler = getattr(views,endpoint) response = handler(request,**values) except HTTPException, e: response = e return ClosingIterator(response(environ,start_response), [session.remove,local_manager.cleanup])
このコードの大部分が始まりです。
ステップ by ステップで進めていきましょう。
最初に一組のインポート文があります。
From SQLAlchemyは新しいデータベースエンジンを生成するファクトリ関数をインポートしています。
database engineは、データベース管理と、コネクションプールを保持しています。
次にWerkzeugネームスペースが提供しているいくつかのオブジェクトインポートがあります。
requestオブジェクト、リクエストの終了時に後始末を行ってくれる特別なイテレータ、
そして全てのHTTP exceptionのためのベースクラスです。
私たちがutilsモジュールをまだ書いていないので、次の5つのインポートは動作しません。
しかしながら、オブジェクトのうちのいくつかを既にカバーすべきです。
sessionオブジェクトはPHP風のセッションオブジェクトではなくSQLAlchemyデータベースセッション
オブジェクトです。基本的にデータベース・セッション・オブジェクトはデータベース用に、
まだコミットされていないオブジェクトを追跡します。
Djangoとは異なり、インスタンス化されたSQLAlchemyモデルは、セッションによって
既に追跡されています!メタデータオブジェクトはさらに、テーブル情報を追跡するために
SQLAlchemyに使用されます。
デベロッパは、全てのデータベース用テーブルを作成するためにメタデータ・オブジェクトを
容易に使用できます。また、SQLAlchemyは、外部キーおよび同様の材料を調べるために
それを使用します。
localオブジェクトは、ユーティリティモジュールに作成する基本的名スレッドローカルオブジェクトです。
このオブジェクト上の全ての属性は現在のリクエストに結び付けられます。
私たちは、暗黙にスレッドセーフな方法で、このオブジェクトを利用することができます。
local_managerオブジェクトは、リクエスト終わりで全てのlocalオブジェクト(スレッドローカル)
のプロパティ削除のための追跡方法を保持しています。
URLルーティング情報を保持するURLmapを最後にインポートしています。
比較することができるDjangoを知っているなら、urls.pyモジュールにURLパターンを指定することができる。
PHPを使用しているなら、ビルトインの"mod_rewrite"と比較可能です。
デベロッパは、全てのモデルを保持しているmodelsモジュールとビュー関数を保持しているviewsモジュールを
インポートします。
たとえインポートを使わないとしても、全てのテーブルがメタデータプロパティ上に登録されるように
そこにあります。
それでは、アプリケーションクラスを見てみましょう。
このクラスのコンストラクタは、データベースのタイプおよび、データベースログインクレデンシャル(信任状)
か、データベースロケーションをさすデータベースURIを受け取ります。
SQLiteの例は次のとおりです。'sqlite:////tmp/shorty.db'(スラッシュは4つです)
コンストラクタでは、データベースURIでdatabase engineを生成し、convert_unicodeパラメータで
SQLAlchemyにstringを全てunicodeオブジェクトに変換するよう伝えます。
他には、local object(スレッドローカル)へアプリケーションを拘束しています。
これは、実際必要ありません。ただし、python shellでアプリケーションを弄りたければ
有用です。
アプリケーションをインスタンス化することで、カレントスレッドを拘束します。
そして全てのデータベース関数は、想定どおり動作するでしょう。
もしスレッド拘束を行わなければ、Werkzeugは、SQLAlchemyのためのセッションを作っている場合
データベースを見つけることができないと苦情を吐くでしょう。
コンストラクタの下に定義されているinit_database関数は、使用する全てのテーブルを作成するために
使用することができます。
その定義の後に、リクエストをディスパッチする関数が定義されています。
ここでは、Requestクラスのコンストラクタにenvironment(環境)を渡すことによって、
新しいrequestオブジェクトを生成しています。さらにもう一度、スレッドローカルにアプリケーションを
拘束しています。拘束を行わなければ、アプリケーションはまもなく壊れます。
このとき、URL mapに現在のWSGI environmentオブジェクトで関連付けられている
新しいURL map adapterを生成します。これは、基本的に、入ってくるリクエスト情報の環境を
判断して、それが必要とする環境から情報を取得します。
これは例えば外部URLのためのサーバーの名前、スクリプトのロケーションなどです。
そのため、私たちはURL builderを使用して絶対パスを生成することができます。
さらに、utilsモジュール中でadapterをURL生成に使用することができるように、
私たちはアダプターをローカル(スレッドローカル)に拘束します。
その後、1つの、try/exceptで、HTTP exceptionをキャッチしています。
これは、adapterがマッチングしている間、あるいはビュー関数の中で生じるかもしれない
HTTP exceptionを補足しているのです。
アダプターが私たちの現在のリクエスト用の妥当なendpointを見つけない場合、
それは、私たちがレスポンス・オブジェクトのように使用することができるNotFound例外を投げるでしょう。
endpointは基本的に私たちがリクエストを扱いたい関数の名前です。
私たちは、endpointの名前を持った関数をちょうど得て、それにリクエストおよびURL値を渡します。
関数の最後では、response objectをWSGIアプリケーションとして呼び出しています。
そして、この関数の戻り値(iterableとして)にclosing iterator classとともに、後始末用コールバック関数を渡します.
(callbacks:スレッドローカルの保持するデータのクリーンアップ、カレントSQLAlchemyセッションの削除)
次のステップでは、新たに2つの空ファイルshorty/views.pyとshorty/models.pyをつくります。
だから、事前にインポートしています。後で、この二つのファイルについてコードしていきます。
Part 2 : Utilities
今までで、基本的に、WSGIアプリケーション自体の実装は終了しています。しかし、
インポートしているクラスや関数が動作するように、utilityモジュールへさらにいくらかの
コードを加える必要があります。
当分の間、私たちは、アプリケーション動作に必要なオブジェクトを追加していくことになります。
以下に shorty/utils.pyファイルのコードを示します。
#!/usr/bin/env python # -*- coding: cp932 -*- # The Utilities from sqlalchemy import MetaData from sqlalchemy.orm import create_session, scoped_session from werkzeug import Local, LocalManager from werkzeug.routing import Map, Rule local = Local() local_manager = LocalManager([local]) # proxy objectが返る application = local('application') metadata = MetaData() session = scoped_session(lambda: create_session(application.database_engine, transactional=True),local_manager.get_ident) url_map = Map() def expose (rule, **kw): def decorate(f): kw['endpoint'] = f.__name__ url_map.add(Rule(rule,**kw)) return f return decorate def url_for(endpoint, _external=False, **values): return local.url_adapter.build(endpoint, values, force_external=_external)
そして、既知のlocal object(スレッドローカル)とlocal managerオブジェクトを生成します。
ここで新しいことは、local objectをstringと共に呼び出すとproxy objectが返ることです。
この返ってきたプロキシは、常にlocal object上のその名前(local.__call__("application"))をもった属性を指します。
For example application now points to local.application all the time.
(local.applicationは常に、applicationをさします)
しかしながら、もし上のことを行わなかった場合、local.applicationには何もオブジェクトが拘束されていないので
RuntimeErrorを得ることになるでしょう。
次の3行は、SQLAlchemy0.4 またはそれ以降のバージョンで動作するWerkzeugアプリケーションで基本的に必要です。
私たちは、全てのテーブルのために新しいmetadataを生成します。そしてそのときに、scoped_session ファクトリ関数
を使って新しいscoped_sessionを生成します。
これは、基本的に、werkzeug localが行うよう、カレントコンテキストを決定し、かつ、
現在のアプリケーションのデータベース・エンジンを使用するために同じアルゴリズムを使用するよう
SQLAlchemyに命令します。
もし、同一pythonインタプリタ上でアプリケーションオブジェクトの複数インスタンス化を提供したくないなら、
別の箇所でも、カレントlocal objectからアプリケーションオブジェクトを引くコードを無くせばシンプルになります。
この方法は、Djangoでも使われています。しかし、複数のこのようなアプリケーションオブジェクトの結合を不可能にします。
残りのモジュールは、私たちがviewsモジュールで使用するコードです。
基本的なアイディアとしては、Djangoのようなセントラルurls.pyや、PHPがやるようなURLリライトのための.htaccessではなく、
decoratorsを利用して、ビュー関数のためのURLディスパッチルールを決定する方法です。
これは一つの方法にすぎません。ルール定義のハンドル方法は無数にあります。
utils.pyのurl_for関数は、endpointによってURLを生成する単純な方法を提供します。
私たちは、viewsやmodelモジュールでこの関数を利用することになります。
Intermission : And Now For Something Completely Different
(休憩:全然関係ない話)
あなたは、日々の似通っている開発タスクに多くの時間がさかれています。
そのうちの一つが開発サーバーの立ち上げ(もし、あなたがphpユーザーなら:Werkzeugは、開発のためにApacheに依存しません。
完璧に素晴らしい推奨方法は、開発用pythonに同梱されているwsgiref serverを利用することです。)、次にpythonインタプリタを
開始させてdatabase modelsとの格闘、データベースを初期化、などなど、
Werkzeugはそのようなmanagement scriptsを信じられないくらい簡単に作成します。
以下に完全にフィーチャーされたmanagement scripts実装を示します。
最初に作成したmanage.pyファイルの中にこの実装を入れます。
#!/usr/bin/env python # -*- coding: cp932 -*- # manage.py from werkzeug import script def make_app (): from shorty.application import Shorty return Shorty('sqlite:////tmp/shorty.db') def make_shell (): from shorty import models,utils application = make_app() return locals() action_runserver = script.make_runserver(make_app,use_reloader=True) action_shell = script.make_shell(make_shell) action_initdb = lambda : make_app().init_database() script.run()
werkzeug.script は、script documentation(file:///C:/Python25/Lib/site-packages/werkzeug-0.4.1-py2.5.egg/docs/script.html)
で詳細に説明してあるのでここでは割愛します。
もし、上述したコードと、あなたのコードの比較と行番号による例外チェックを行いたいなら。
何が重要かというと、python manage.py shellを実行することで、tracebackなしで、インタラクティブpythonインタプリタが
取得できるということです。
すぐにでも、スクリプトを走らせて、database modelsモジュールを書き始めることができるのです!ひゃっほー!
Part 3 : Database Models
既に私たちはmodelsモジュールを作ることができます。
なぜなら、applicationは、tableと一つのモデルだけを持つシンプルでprettyなものだからです。
#!/usr/bin/env python # -*- coding:cp932 -*- # models.py from datetime import datetime from sqlalchemy import Table , Column, String, Boolean, DateTime from shorty.utils import session,metadata,url_for,get_random_uid url_table = Table('urls',metadata, Column('uid',String(140),primary_key=True), Column('target',String(500)), Column('added',DateTime), Column('public',Boolean) ) class URL(object): def __init__(self, target, public=True, uid=None, added=None): self.target = target self.public = public self.added = added or datetime.utcnow() if not uid: while True: uid = get_random_uid() if not URL.query.get(uid): break self.uid = uid @property def short_url(self): return url_for('link',uid=self.uid,_external=True) def __repr__(self): return '<URL %r>' % self.uid session.mapper(URL, url_table)
このモジュールは、かなり真っ直ぐです。テーブル作成に必要なSQLAlchemyモジュールを全てインポートします。
そして、このテーブルのために、クラスを加えて、マッピングします。
SQLAlchemyに関する詳細な説明に関しては、excellent tutorial(http://www.sqlalchemy.org/docs/04/ormtutorial.html)
を見ましょう。
コンストラクタでは、自由に使用できるIDが見つかるまで、ユニークなIDを生成します。
sqlalchemy.utils.get_random_uid関数が見当たらないことにならないように、sqlalchemy.utilsモジュールに
追加しておきましょう。
今回は、606行目あたりに以下のget_random_uid関数を追加しておきました。
# For Werkzeug Tutorial Application util function URL_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' def get_random_uid (): from random import sample, randrange return ''.join(sample(URL_CHARS, randrange(3,9)))
今日はここまで。
trac-jaいれた
Trac |
trac入れたときのメモ。
まぁ、いわずと知れたtracです。
修正BSDライセンス
[構成]
apache2.2 + mod_python + trac-ja
[特徴]
svn,git,hg,bzrといったバージョン管理システムのwebインタフェースを提供
[必須stuff]
python(自分の環境はpython2.4)
sqlite3 ※ python2.5 laterなら同梱されてるから必要ないです。
easy_install
$ wget http://www.i-act.co.jp/project/products/downloads/Trac-0.11.2.1.ja1.zip
$ cd Trac-0.11.2.1.ja1
$ sudo python setup.py install
running install
running bdist_egg
running egg_info
creating Trac.egg-info
writing requirements to Trac.egg-info/requires.txt
writing Trac.egg-info/PKG-INFO
writing top-level names to Trac.egg-info/top_level.txt
writing dependency_links to Trac.egg-info/dependency_links.txt
writing entry points to Trac.egg-info/entry_points.txt
writing manifest file 'Trac.egg-info/SOURCES.txt'
reading manifest file 'Trac.egg-info/SOURCES.txt'
writing manifest file 'Trac.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-i686/egg
running install_lib
running build_py
...
Installed /usr/lib/python2.4/site-packages/Genshi-0.5.1-py2.4-linux-i686.egg
Searching for setuptools==0.6c9
Best match: setuptools 0.6c9
Processing setuptools-0.6c9-py2.4.egg
setuptools 0.6c9 is already the active version in easy-install.pth
Installing easy_install script to /usr/bin
Installing easy_install-2.4 script to /usr/bin
Using /usr/lib/python2.4/site-packages/setuptools-0.6c9-py2.4.egg
Finished processing dependencies for Trac==0.11.2.1.ja1
[tracプロジェクト作成]
trac-adminを利用してTrac environmentを作成。インストールが正常終了していれば利用できる。
$ sudo mkdir -p /usr/local/trac/projects/dev/
$ trac-admin /usr/local/trac/projects/dev initenv
※tracEnvを作成するのに必要な情報が聞かれます。
・プロジェクト名
・データベースコネクションストリング ※デフォルト:sqlite
・リポジトリパス ※/usr/local/trac/projects/dev
$ # Trac environmentの所有者をapacheユーザーに変更
$ sudo chown -R apache:apache /usr/local/trac/projects/
$ # 動作確認
$ sudo tracd --port 8001 /usr/local/trac/projects/dev #port 8001でアクセス。メインページが見れたらおk
[Trac設定]
・匿名ユーザーからロールを剥奪
$ sudo trac-admin /usr/local/trac/projects/dev permission remove anonymous TICKET_CREATE TICKET_MODIFY WIKI_CREATE WIKI_MODIFY
・チケットプロパティの日本語化
$ sudo trac-admin /usr/local/trac/projects/dev/ ticket_type add タスク-task
$ sudo trac-admin /usr/local/trac/projects/dev/ ticket_type add 機能追加/変更-enhancement
$ sudo trac-admin /usr/local/trac/projects/dev/ ticket_type add 不備/不具合-defect
$ sudo trac-admin /usr/local/trac/projects/dev/ ticket_type remove defect
$ sudo trac-admin /usr/local/trac/projects/dev/ ticket_type remove task
$ sudo trac-admin /usr/local/trac/projects/dev/ ticket_type remove enhancement
[Trac plugins]
プラグイン公開サイト:http://www.trac-hacks.org/wiki/
・TicketImportPlugin : http://trac-hacks.org/wiki/TicketImportPlugin
Excel , CSV形式のファイルを読み込んでチケットを登録するためのプラグイン
$ sudo easy_install http://trac-hacks.org/svn/ticketimportplugin/0.11 # CSV読み込みできる
$ sudo easy_install xlrd # Excelの読込ができる。
$ # trac.iniの編集
$ sudo vi /usr/local/trac/projects/dev/conf/trac.ini
[components]
talm_importer.importer.* = enabled
IMPORT_EXECUTE権限を付与(htpasswdでBasic認証を行う予定なので、authenticatedユーザーに対して付与)
$ sudo trac-admin /usr/local/trac/projects/dev/ permission add authenticated IMPORT_EXECUTE
・XmlRpcPlugin : http://www.trac-hacks.org/wiki/XmlRpcPlugin
eclipse mylyn pluginと連携するときに必要なのでインストール
$ sudo easy_install http://trac-hacks.org/svn/xmlrpcplugin/trunk/
TRAC_ADMIN権限を持っているアカウントで、tracにログインして、管理からプラグインを選択。
XmlRcpPluginが表示されるので、全て選択し適用。
XML_RPC権限を付与
$ sudo trac-admin /usr/local/trac/projects/dev/ permission add authenticated XML_RPC
[apache confファイル]
httpd.confでincludeするconfファイルを作成。以下定義内容。
# trac Location directive
<Location /trac>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /usr/local/trac/projects/
#PythonOption TracUriRoot /xxx/xxx
PythonDebug on
</Location>
# trac login LocationMatch directive
<LocationMatch "/trac/.*/login">
AuthType Basic
AuthName "trac"
AuthUserFile "/usr/local/trac/projects/.htpasswd"
Require valid-user
</LocationMatch>
おわり。
MoinMoin 1.8.1 入れたときのメモ(CentOS5.2 final)
MoinMoin構成
apache2.2 + mod_wsgi + MoinMoin1.8.1
[特徴]
DB依存なし。
ページリビジョン管理(変更履歴は全て保存される->だから重い)
UTF-8対応
拡張マクロ、テーマとか(http://moinmo.in/MoinMoinExtensions)
[事前準備]
apache2-threaded-dev #apxs2がmod_wsgiのビルドに必要っぽいので。
httpd-devel #一応、apxsもいれとく
mod_wsgi2.1-2.el5.i386 # mod_wsgi
[moinmoin導入]
$ sudo wget http://static.moinmo.in/files/moin-1.8.1.tar.gz $ #展開する $ gzip -dc moin-1.8.1.tar.gz | tar xvf - $ cd moin-1.8.1 $ #setup.pyを叩いてインストール & record install log $ #--prefix指定なしなので、標準インストール /usr/share/moinにインストールされます。 $ #MoinMoinのpythonモジュールは、PYTHONPATHに配置されます。 $ #私の環境では、/usr/lib/python2.4/lib/site-packages/MoinMoin $ sudo python setup.py install --record=install.log $ #今回作成するMoinMoinWiki用のディレクトリを作成 $ sudo mkdir -p /usr/local/moin/wiki/ $ #MoinMoinインストールディレクトリから必要なファイル等をディレクトリ毎コピります。 $ export WIKI_HOME=/usr/local/moin/wiki/ $ export MOIN_CONFIG=/usr/share/moin/config/ $ export MOIN_DATA=/usr/share/moin/data/ $ export MOIN_HTDOCS=/usr/share/moin/htdocs/ $ export MOIN_UNDERLAY=/usr/share/moin/underlay/ $ export MOIN_SERVER=/usr/share/moin/server/ $ sudo cp -R $MOIN_CONFIG $WIKI_HOME $ sudo cp -R $MOIN_DATA $WIKI_HOME $ sudo cp -R $MOIN_HTDOCS $WIKI_HOME $ sudo cp -R $MOIN_UNDERLAY $WIKI_HOME $ sudo mkdir -p $WIKI_HOME/apache # <- mod_wsgiが参照するディレクトリを掘る $ sudo cp -v $MOIN_SERVER/moin.wsgi $WIKI_HOME/apache/ $ # mod_wsgi用の設定ファイル編集 $ sudo vi $WIKI_HOME/apache/moin.wsgi 以下オリジナルとのdiff < sys.path.insert(0, '/usr/lib/python2.4/site-packages') --- > sys.path.insert(0, '/usr/local/moin/wiki/config/') $ # Wikiコンフィグレーションファイル wikiconfig.pyを編集 $ cd $WIKI_HOME/config/ $ sudo vi wikiconfig.py 以下オリジナルとのdiff < # -*- coding: utf-8 -*- --- > # -*- coding: iso-8859-1 -*- 9d8 < 37c36 < sitename = u'Develop Team Wiki' --- > sitename = u'Untitled Wiki' 50c49 < page_front_page = u"FrontPage" --- > #page_front_page = u"FrontPage" 70c69 < data_dir = '/usr/local/moin/wiki/data/' --- > data_dir = '/usr/local/apache/html/moin/data/' 78c77 < data_underlay_dir = '/usr/local/moin/wiki/underlay/' --- > data_underlay_dir = '/usr/local/apache/html/moin/underlay/' 87c86 < url_prefix_static = '/moin_static181' --- > #url_prefix_static = '/moin_static181' 94c93 < superuser = [u"specialuser", ] --- > #superuser = [u"YourName", ] 99c98 < acl_rights_before = u"specialuser:read,write,delete,revert,admin" --- > #acl_rights_before = u"YourName:read,write,delete,revert,admin" 104c103 < password_checker = None # None means "don't do any password strength checks" --- > #password_checker = None # None means "don't do any password strength checks" 143d141 < #theme_force = True 145,147c143 < #theme_force = True < theme_default = 'modern' < #theme_default = 'sinorca4moin' < #theme_default = 'explorer' < #theme_default = 'simplemente' --- > 155c151 < language_default = 'ja' --- > language_default = 'en'
[今まで行った作業]
・MoinMoinの標準インストール
PREFIX/lib/pythonX.Y/site-pacakges/MoinMoinにモジュール群が配置されます。
/usr/share/moin/直下に構成ファイルなどのテンプレートが配置されます。
ディレクトリ構成は以下のとおりです。
/usr/share/moin/
/data/ (wiki pages, users, etc) - 当ディレクトリはMoinMoinのみがアクセスすべきディレクトリ
/underlay/ (wiki pages) - 当ディレクトリはMoinMoinのみがアクセスすべきディレクトリ
/htdocs/ (htmlサポートファイル[テーマとか,imageとか]) - apacheが参照するディレクトリ。シムリンクでもお好きに。
/server/ (MoinMoinスタートアップファイル配置ディレクトリ)
/config/ (MoinMoinコンフィグレーションファイル配置ディレクトリ)
[Apache2.2 + mod_wsgi]
mod_wsgiはyumでインストールしているので、apacheモジュールディレクトリに配置されています。
moinmoin用のconfファイルを作成して、httpd.confでincludeします。
以下confファイル定義。
# wsgi_module load LoadModule wsgi_module modules/mod_wsgi.so # moinmoinで利用する静的コンテンツ置き場へのエイリアスディレクティブ定義 Alias /moin_static181 /usr/local/moin/wiki/htdocs/ # /moin_static181のDirectoryディレクティブ定義 <Directory /moin_static181> Order deny,allow allow from all </Directory> # WSGIScripAliasディレクティブ WSGIScriptAlias /wiki /usr/local/moin/wiki/apache/moin.wsgi # moin.wsgiをmod_wsgiがハンドルできるようにDirectoryディレクティブ定義 <Directory /usr/local/moin/wiki/apache> Order deny,allow Allo from all SetHandler wsgi-script Options ExecCGI </Directory>
apacheが見るディレクトリの権限をリカーシブでapacheユーザーに変更。
gracefulしてhttp://my.domain/wiki/へアクセスしてFrontPageが表示されれば成功。
あとは、各利用ユーザの権限管理とかをよきにはからえばおk