symfony 1.1 でのsfFormを使用する際の文字化けの解消

symfony 1.1 のフォームを使用すると、明らかな文字化けではないが、文字列の最後に?がつくなどの文字化けをすることがありました。

原因は、サイトの都合上、phpの内部コードと外部コードを別々にしなければならない案件があり、外はSJIS、中はEUCとしていたため、htmlspecialcharsでの文字コード指定時に外側用のSJISとして適用されていたためだったようです。これを調べる過程でどこかのサイトで、理論的にはhtmlspecialcharsで文字コードの指定をしても、日本語については何の意味もないというような記事があったが、実際には変わるようです。少なくとも今回はそれで解消しました。

実際に行ったのは、下記のコードをeucForm.class.phpとして、(このフォームの使用範囲に応じて)symfonyプロジェクトディレクトリ直下のlibか、apps/appname/libか、モジュールのlibかにおいて、フォームを使用する際はsfFormをextendsして使うのではなくeucFormをextendsして使用すれば大丈夫です。他にももしかしたら方法があるのかもしれませんが、時間もなかったのでとりあえずこれで切り抜けました。

< ?php

/**
 * eucForm class
 *
 * 文字コードの指定(EUC-JP)
 *
 */
class eucForm extends sfForm
{
  public function setup()
  {
    //文字コードの指定
    foreach($this->widgetSchema->getFields() as $widget){
      $widget->setCharset('EUC-JP');
    }
    parent::setup();
  }

}

これだけです。このEUC-JPと直接書きこんでいるところを、設定ファイルからsfConfig::get(‘app_internalencoding’)などとやって、app.ymlにinternalencoding: EUC-JP と書くことで汎用性を持たせるのもありかもしれませんが、そもそも内部コードにSJISを持たせることは考えにくいし、UTF-8なら変換の必要はないし、と考えるとこのようなことをやらなければならないのは、内EUC-JP、外SJISに限られるかなと思ってEUC-JP専用にしてしまいました。

symfonyを使用する際はできるだけ外も内もUTF-8を使用するようにしていますが、いろいろな都合でそうもいかないことも時にはあります。 それでもphp.iniや.htaccessで文字コードを適切に指定しておけば、あまり問題が起こることはないのですが、今回のように問題になることもあります。

symfony 1.1 のsfFormの情報

symfony 1.1のRC1がでて、間もなくリリースされるという状況ではありますが、ドキュメントについては非常に少ない状態です。

1.1の大きな目玉の一つであるフォームフレームワークについては、なかなか情報が見つかりませんでした。symfonyのサイトにあるドキュメントもまだ1.0の情報のままで、1.1では特別な指定をしない限り使用できなくなりますのと注意書きがあります。

理解すると、前のにくらべてとても使いやすく自由度が高いので非常に便利です。

情報をあさっていくうちに、参考になるサイトを見つけたので紹介します。どちらも英語ですが、コードを見るだけでも参考になると思います。

  • 7 Days of Symfony 1.1 – Forms, Widgets and Validators
    このリンクはDay1ですが、7までありとても詳しく解説されていて参考になります。
  • symfony 1.1 form framework and the MVC pattern
    symfonyの作者であるfabien自身が自分のブログで書いた記事です。チュートリアルではなく、このフォームフレームワークがMVCモデルであることを説明しているページですが、簡潔にコードでも説明していて参考になります。

tracのpriority等の初期設定

tracでプロジェクトをセットアップすると、デフォルトでpriority等が設定されているが、これを日本語化して分かりやすいように設定する。

trac-admin /path/to/tracproject

これで対話モードになる。
そこで、

ticket_type change defect 不具合
ticket_type change enhancement 追加機能
ticket_type change task やること
priority change blocker 最優先
priority change critical 優先
priority change major 普通
priority change minor 低い
priority change trivial 最も低い
component rename component1 コード
component rename component2 ドキュメント
severity add 作業できない
severity add 致命的
severity add 重大
severity add 普通
severity add 軽微
severity add 些細

をやると一通り日本語になる。
必要に応じて変更して利用してください。

日本語を決める時に参考にしたサイト

http://discypus.jp/trac/sandbox/wiki/WikiStart

tracを日本語化

yum でインストールしたtracをそのまま使用していたが、自分以外の人も使うことになったので、日本語化することにした。
日本語化は非常に簡単。

まず、yumでインストール済みのtracをアンインストール。その後インタアクト株式会社–業務内容–公開資料:
の一番下のtrac-0.10.4-ja-1をダウンロードして適当な場所に保存し、展開後インストール。
実際のコマンドは下記。

yum remove trac
wget http://www.i-act.co.jp/project/products/downloads/trac-0.10.4-ja-1.zip
unzip trac-0.10.4-ja-1.zip
cd trac-0.10.4-ja-1
python ./setup.py install

以上で完了。

なお、既に作成済みのプロジェクトについては、wikiは日本語化されない。これをしたい場合は、

 trac-admin /path/to/tracproject wiki load /usr/share/trac/wiki-default

で行うが、編集済みのwikiは失われる。

Subversion(svn)で最初の空のレイアウトを作成

Subversionでバージョン管理をする際に、trunkだとかbrunchesだとかを作成して管理することが多い。その時のレイアウトはだいたい決まっているので、そのレイアウトの作成方法をメモ。
svn bookのCreating the Layout, and Importing Initial Dataを参考、というよりもほぼそのまま。

$ mkdir tmpdir
$ cd tmpdir
$ mkdir projectA
$ mkdir projectA/trunk
$ mkdir projectA/branches
$ mkdir projectA/tags
$ mkdir projectB
$ mkdir projectB/trunk
$ mkdir projectB/branches
$ mkdir projectB/tags
…
$ svn import . file:///path/to/repos --message 'Initial repository layout'
Adding         projectA
Adding         projectA/trunk
Adding         projectA/branches
Adding         projectA/tags
Adding         projectB
Adding         projectB/trunk
Adding         projectB/branches
Adding         projectB/tags
…
Committed revision 1.
$ cd ..
$ rm -rf tmpdir
$

レイアウトは状況に応じて、あるいは好みで変えればいいと思いますがこのように最初にレイアウトを作っておくと便利。

このあと、実際にコミットしたいディレクトリで、例えば
svn://SERVERNAME:3690/path/to/repos/projectA/trunk/
をいったんチェックアウトすれば、以降はsvn commitでそのディレクトリをprojectAのtrunkとしてコミットできるようになる。

PostgreSQL8.3のインストール(8.2からのアップグレード)

PostgreSQL8.3よりXML型が使えるようになる等、XMLサポートが少し追加された。この機能を利用したいので8.3にアップグレードする。

XMLサポートを有効にしてインストールしたいのでlibxml2のアップグレードを先に行う。

libxmlのインストール

# wget ftp://gd.tuwien.ac.at:21/pub/libxml/libxml2-2.6.31.tar.gz
# tar xvzf libxml2-2.6.31.tar.gz
# cd libxml2-2.6.31
# ./configure --prefix=/usr/local
# make
# make install

ダンプ

8.2で稼働しているデータはそのままでは、8.3では使用できないため、既に登録されているデータが必要な場合は、ここでダンプしておく。

PostgreSQL8.3のインストール

# /etc/init.d/postgresql stop
# wget http://wwwmaster.postgresql.org/redir?http%3A%2F%2Fftp3.jp.postgresql.org%2Fpub%2Fdb%2Fpostgresql%2F%2Fsource%2Fv8.3.1%2Fpostgresql-8.3.1.tar.gz
# tar xvzf postgresql-8.3.1.tar.gz
# cd postgresql-8.3.1
# ./configure --with-libxml
# gmake
# gmake install

8.2が稼働していた場合は、/usr/local/pgsql/dataが既にあり、8.3を起動したときにこれを利用しようとするため、起動できない。そこで、このディレクトリを削除する。(ここでは念のため、data.oldにmoveしている)

# mv /usr/local/pgsql/data /usr/local/pgsql/data.old

エンコードの指定

ここで、いったん/etc/sysconfig/i18nのlangの設定を使用したいDBの
エンコード設定に変更しておく
例.

lang="ja_JP.utf8"

=> UTF8になる

lang="ja_JP"

=> EUC-JPになる

これまでと違い同一data内で異なるエンコードの使用ができないので注意

# /etc/init.d/postgresql start

これでdataディレクトリも作成される。
PostgreSQL8.2等がインストールされていない状態の場合は、この自動起動ファイルの作成も必要。
PostgreSQL8.2のソースインストールを参照。
※ この自動起動ファイルも8.2の個所を8.3にしておく。

当然、dataディレクトリ内の設定が変わっているので
/usr/local/pgsql/data/postgresql.conf
/usr/local/pgsql/data/pg_hba.conf
等の設定をそれぞれ修正。

postgresql.confについては試していないが、pg_hba.confについては前のものをコピーでもOK

# cp -p /usr/local/pgsql/data.old/pg_hba.conf /usr/local/pgsql/data/

PostgreSQLの再起動

# /etc/init.d/postgresql restart

リストア

必要に応じてリストアを行う。

PostgreSQL8.2のソースインストール

既存の(rpm版)PostgreSQLのアンインストール

rpm版のPostgreSQLが入っている場合これをアンインストールしてからインストールします。

/etc/init.d/postgresql をとっておく

cp /etc/init.d/postgresql /tmp

rpm版PostgreSQLのアンインストール

rpm -e postgresql-devel
rpm -e postgresql-pl
rpm -e postgresql-test
rpm -e postgresql-server
rpm -e freeradius-postgresql
rpm -e postgresql-contrib
rpm -e postgresql-docs
rpm -e postgresql

PostgreSQL8.2のインストール

ソースのダウンロード

cd /root/install/arc
wget ftp://ftp.jp.postgresql.org/source/v8.2.7/postgresql-8.2.7.tar.gz

解凍

tar xvzf postgresql-8.2.7.tar.gz

インストール

cd postgresql-8.2.7
./configure
gmake
su
gmake install
adduser postgres
mkdir /usr/local/pgsql/data
chown postgres /usr/local/pgsql/data
su - postgres
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
/usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data >logfile 2>&1 &

※postgresのshellがbashでないと、「曖昧なリダイレクト出力です」と表示される
⇒/etc/passwd でpostgres のシェルをbashに変更(vipw)

正常にインストールされているかのテスト

/usr/local/pgsql/bin/createdb test
/usr/local/pgsql/bin/psql test
/usr/local/pgsql/bin/dropdb test

自動起動ファイルの設定

/etc/init.d/postgresql の編集
先ほどコピーしておいた /root/postgresql を下記の通り編集し
/etc/init.d/postgresql として保存します。

PGVERSION=8.2.1 (7.4.*⇒8.2.7に)

export PGDATA=/var/lib/pgsql

をコメントアウトし

export PGDATA=/usr/local/pgsql

export PGDATA=/var/lib/pgsql/data

をコメントアウトし

export PGDATA=/usr/local/pgsql/data

自動起動の設定

chkconfig --level 345 postgresql on

ライブラリの適用

/etc/ld.so.conf に /usr/local/pgsql/lib を追加し

ldconfig -v

pythonでPILを使って画像縮小と明るさ調整

最近ちょっとpythonを使い始めたのですが、今はWindowsで、大量の画像のサムネール作成とかちょっとしたバッチ処理にだけ、使っています。その際に明るさを少し明るくしたかったのですが、その時のメモ。

画像縮小と明るさ調整

import Image, ImageEnhance
im = Image.open("C:temptemp.jpg")
im.thumbnail((400, 400), Image.ANTIALIAS)
eim = ImageEnhance.Brightness(im)
eim.enhance(1.5).save("C:temptemp_brightimage.jpg","JPEG",quality=95)

400, 400 はサイズ。横、縦、それぞれの最大サイズで、大きい方をこれにあわせて、小さい方は自動的に計算してくれる
enhance(1.5)の1.5は0.0が黒画像で、1.0がオリジナル。

ディレクトリ内の一括処理について

上記は画像一枚だけの処理ですが、

import sys, glob
for infile in glob.glob(sys.argv[0]):

とかやることで、特定のディレクトリ内のファイルを全て処理するスクリプトも簡単に作れます。実際に作ったものは、適当であまりきれいではないので、非公開ということで・・・。

参考

日本麻酔科関西地方学会・・・なぜかここにありました。
The ImageEnhance Module・・・Python Imaging Library Handbookの中の説明

phpでXMLとXSLTでHTMLをつくる(XSLTプロセッサ)

XSLTプロセッサとは

XSLTプロセッサとはXSLTを使ってXMLを他のXMLに変換するものです。タイトルではHTMLをつくるとなっていますが、実際にはHTMLでなくてもいいわけです。

XSLTとは

XSLTとは、まさに上記の目的(XMLを他のXMLに変換する)のための簡易言語で、これもXMLで書かれています。
XSLTの書き方はサンプルで覚えるXSLTプログラミングが参考になります。

phpによる変換

PHPマニュアル XSL関数より

PHP 5には、デフォルトでXSLエクステンションが含まれており、 configureに引数–with-xsl[=DIR] を追加することにより有効にすることができます。

なのでとても簡単にできます。下記が例です。($xml に xmlの内容が格納されており、/path/to/xslfile.xslにxsltファイルがあることを想定しています。)

$doc = new DOMDocument();
$xsl = new XSLTProcessor();

$doc->load('/path/to/xslfile.xsl');
$xsl->importStyleSheet($doc);

$doc->loadXML($xml);
echo $xsl->transformToXML($doc);

ここでは、$doc->loadXML($xml);としていますが、これは$xml内に既にXMLの内容が格納されていると想定しているからです。たとえばDBからとってきた場合などです。ファイルから直接読み込むのであれば、XSLTの読み込みと同じように$doc->load(‘/path/to/xmlfile.xml’);でもOKです。
これだけで、変換が完了します。

htmlファイルからPDFの作成 [CentOS]

htmlファイルからPDFを作成する方法はいろいろあるが、無料で実現できて、cssを駆使したページでもかなりきれいに表示させる方法としては、mozilla2ps + XULRunner + ps2pdfがベストだと思います。

この方法だとXが必要になりますが、ここでは仮想フレームバッファを使用することで回避しています。
必要な作業は

  • XULRunnerのインストール
  • mozilla2psのインストール
  • Xvfb(仮想フレームバッファ)の自動起動設定
  • (ps2pdfでpdfに変換)

です。

XULRunnerのインストール

XULRunner 1.8.0.4 Release Notes – MDCからダウンロードします。

wget http://ftp.mozilla.org/pub/mozilla.org/xulrunner/releases/1.8.0.4/linux-i686/en-US/xulrunner-1.8.0.4.en-US.linux-i686.tar.gz
tar xvzf xulrunner-1.8.0.4.en-US.linux-i686.tar.gz
su
mkdir -p /opt/xulrunner/1.8.0.4/
mv xulrunner /opt/xulrunner/1.8.0.4/
cd /opt/xulrunner/1.8.0.4/xulrunner/
./xulrunner --register-global

mozilla2psのインストール

Michele Baldessari – Homepageよりダウンロードします。

wget http://michele.pupazzo.org/mozilla2ps/download/mozilla2ps-0.6.xulapp
/opt/xulrunner/1.8.0.4/xulrunner/xulrunner --install-app mozilla2ps-0.4.xulapp /tmp

これで/tmpディレクトリにインストールされる。/tmpはインストールしたいディレクトリを指定します。
指定しなかった場合は、/usr/lib/foo bar inc./にインストールされます。

Xvfbの自動起動設定

XULRunnerを実行するにはXが起動している必要があります。ただ、今回サーバでXは起動したくないので、Xvfb(仮想フレームバッファ)を利用します。

/usr/X11R6/bin/Xvfb :1 -screen 0 1024x768x8 &

のようにすることで起動は可能なのですが、xvfb-runというのを使用すれば、コマンドの実行中だけ自動的に起動させておくことができます。ただし、これのCentOS用のが見つからなかったのですが、xvfb-run.shというのをたまたま見つけたのでこれを使用します。

wget http://svn.exactcode.de/t2/trunk/package/xorg/xorg-server/xvfb-run.sh

これで

xvfb-run.sh /opt/xulrunner/1.8.0.4/xulrunner/xulrunner /tmp/mozilla2ps/application.ini http://www.yahoo.co.jp /tmp/foo.ps

とすることで、/tmp/foo.psというポストスクリプトファイルが出来上がります。
もし、ローカルにあるファイルを変換する場合は

xvfb-run.sh /opt/xulrunner/1.8.0.4/xulrunner/xulrunner /tmp/mozilla2ps/application.ini file:///tmp/temp.html /tmp/foo.ps

のようにします。
これを元にPDFを作成します。

ps2pdfでpdfに変換

ps2pdfはデフォルトで入っていることが多いです。

ps2pdf /tmp/foo.ps /tmp/foo.pdf

これでpdfが作成できます。
あるいは、ImageMagickのconvertを使用しても作成できます。

convert /tmp/foo.ps /tmp/foo.pdf

以上の流れをシェルスクリプト等にしておけば、htmlから自動でpdfが作成できるようになります。

参考サイト

Xvfb – 仮想フレームバッファ – MOYO Laboratory