Tracサイトで複数の文字コードを扱う
Tracサイトで複数の文字コードソースが混在してもちゃんと表示出来るように。
【環境】
- CentOS 5
- Trac 0.10.4-ja-1 (0.11.2.1-jaでも確認)
- Subversion 1.4.4
通常であればひとつのtracサイトにつき、扱える文字コードは trac.ini の、
・・・(略)・・・ [trac] default_charset = utf-8
の一つだけとなり、そこでShift_JISとかのソースをリポジトリブラウザ経由で見るとぐちゃぐちゃになる訳で。どーにかならんもんかと探してみたら発見しました。つ ココ
なんでも、Universal Encoding Detector というのでソースをdefault_charsetで指定された文字コードにエンコする都度charsetを判別→その結果を指定。というのものらしい。と言うわけでインスコしてみた(↓)。
[root@ns1 root]# wget http://chardet.feedparser.org/download/chardet-1.0.1.tgz
--12:56:42-- http://chardet.feedparser.org/download/chardet-1.0.1.tgz
=> `chardet-1.0.1.tgz'
chardet.feedparser.org をDNSに問いあわせています... 67.19.173.100
chardet.feedparser.org|67.19.173.100|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 179,218 (175K) [application/x-tar]
100%[==================================================================>] 179,218 43.95K/s ETA 00:00
12:56:47 (42.23 KB/s) - `chardet-1.0.1.tgz' を保存しました [179218/179218]
[root@ns1 root]# tar zxvf chardet-1.0.1.tgz
[root@ns1 root]# cd chardet-1.0.1
[root@ns1 chardet-1.0.1]# /opt/python2.4.4/bin/python ./setup.py install
running install
・・・(略)・・・
[root@ns1 chardet-1.0.1]# cd /opt/python2.4.4/lib/python2.4/site-packages/trac/mimeview
[root@ns1 mimeview]# vi api.py
ということで、trac本体にあるソース /opt/python2.4.4/lib/python2.4/site-package/trac/mimeview/api.py の編集。太文字が追加したところ。
・・・(略)・・・
from trac.util.html import escape, Markup, Fragment, html
try :
from chardet.universaldetector import UniversalDetector
except ImportError :
pass
__all__ = ['get_mimetype', 'is_binary', 'detect_unicode', 'Mimeview',
'content_to_unicode']
・・・(略)・・・
def get_charset(self, content='', mimetype=None):
"""Infer the character encoding from the `content` or the `mimetype`.
`content` is either a `str` or an `unicode` object.
The charset will be determined using this order:
* from the charset information present in the `mimetype` argument
* auto-detection of the charset from the `content`
* the configured `default_charset`
"""
if mimetype:
ctpos = mimetype.find('charset=')
if ctpos >= 0:
return mimetype[ctpos + 8:].strip()
if isinstance(content, str):
utf = detect_unicode(content)
if utf is not None:
return utf
if 'UniversalDetector' in globals():
vf = StringIO(content)
detector = UniversalDetector()
for line in vf.readlines():
detector.feed(line)
if detector.done: break
detector.close()
del(vf)
cset = detector.result['encoding']
if cset is not None:
return cset
return self.default_charset
挿入先は参考文献のソースと変わらないのですが内容は変えました。この、Advanced usage に書いてあった方法でやると、content の cherset が判明したら処理を抜けてくるので誤判定が少ないはず。
全部 ASCII コードのファイルだと EOF まで探しまくっちゃうというレスポンスに関しては諸刃の剣となりますが
そして、httpdを再起動。これで終了。リポジトリブラウザでソースを表示させるときが若干もたつく感じになりましたが、ぐちゃぐちゃコードが出てくることに比べれば雲泥の差でございます。