Movable Typeカテゴリの記事
モバイルサイトマップの追加 と MT4iの改造
僕の携帯には電話が滅多にかかってこないどころか、メールもほとんど全くこない(せいぜい2日に1通ペースのでメールが来たことすら気づかないことが多い)と、携帯的には圏外な生活をしています。ところが、近頃携帯でブラウザをする頻度が多くなってきました。電車に乗っているちょっとした時間に『はてな』でブックマークコメントを流し読みしたり、アキバにて過去の自分の行動をこのサイトのモバイル版で遡ったりする(特に過去の回路図とかパーツ情報)のが結構多くなりました。そういうわけで、このサイトのモバイル版も使いやすくしようという気になり、2つほど作業をしてみました。なおモバイル版は、MT4iというMovableTypeのデータベースを直接叩いて携帯向けHTMLを生成してくれるcgiを有難く使わせていただいています。
まず一つ目はGoogle先生からモバイルの記事も検索対象になるように、モバイル版のサイトマップを仕込んでみることにしました。方法はGoogle先生のサイトにあるとおりのXMLを作成、登録すればよいのですが、このサイトを生成してくれているMovableTypeにテンプレートを足すことでモバイル版サイトマップも自動生成しようと思います。
MovableType 2.661では管理画面を開いて[Templateの編集]で『新しいインデックステンプレートを作る』を選択、テンプレートの名前、出力ファイル名、自動的に再構築、リンクするファイルをそれぞれ Google Mobile SiteMap、sitemap_mobile.xml、チェック有、空欄にし、テンプレートの中身を以下のようにしました。
<urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0">
<url>
<loc><$MTBlogURL encode_xml="1"$>cgi/mt4i/mt4i.cgi</loc>
<mobile:mobile />
</url>
<MTEntries lastn="9999">
<url>
<loc><$MTBlogURL encode_xml="1"$>cgi/mt4i/mt4i.cgi?mode=individual&eid=<$MTEntryID$></loc>
<mobile:mobile/>
</url>
</MTEntries>
</urlset>
あとは保存、再構築でGoogleのウェブマスターツールからこのXMLのURLを登録すれば完了です。少しつまずいたのは、locタグのURLをXMLエンコード(アンド記号&などが使えない)しなければならないことでした。
もう一つ行った改造は、MT4iのリダイレクト機能についてです。MT4iではリンクが本文中に含まれていると、そのリンクのURLを修正しゲートウェイを通すことでPC向けサイトでも携帯で見られるようにする機能があります。外部のサイトなら勿論これで問題がないのですが、自身のサイトでもこの機能が働いてしまい、自身の携帯記事から自身のPC記事へ飛んでしまうのが不快でした。そこでこの機能を実現している部分のプログラムを書き換えことで、この問題を修正しました。MT4i.cgiを修正します。
# Convert sorce URL to redirector
my $tmpurl = &make_href("redirect", $rowid, 0, 0, $eid);
# URL encode
$url = MT4i::Func::url_encode($url);
$url = $tmpurl . '&url=' . $url;
my $archive_url = $blog->archive_url;
if($url =~ /^$archive_url(\d{6})\.html/){
$url = &make_href("individual", $rowid, 0, $1 + 0, 0);
}else{
# Convert sorce URL to redirector
my $tmpurl = &make_href("redirect", $rowid, 0, 0, $eid);
# URL encode
$url = MT4i::Func::url_encode($url);
$url = $tmpurl . '&url=' . $url;
}
このサイトのPC記事は(アーカイブディレクトリ)/(6桁のID番号).htmlで保存されているので、その形式のリンクに突き当たった際は、PC記事のURLから携帯記事をURLを割り出すようにしました。PC記事の保存方法が異なる場合でも似たような方法がとれると思います。
今後もモバイル版ともどもよろしくお願いします。
※後になって、最近のコメントがうまく表示されない問題があることに気づきました。その場合は以下の修正を試みてください。
$args{'limit'} = ((!$_[0] || $cfg{NonDispCat}) && $_[1])
? $_[1] * 10 # Limit for recent comment and non-display category specified.
: ($_[1] && !$cfg{NonDispCat}) ? $_[1] : '';
$args{'limit'} = $_[1] ? ($_[1] * ($cfg{NonDispCat} ? 10 : 1)) : '';
if ($_[0] && !$cfg{NonDispCat}) {
if (!$cfg{NonDispCat}) {
MovableType 2.661をapache2+mod_perl2で動作させる
リクエストを戴きましたので、MovableType 2.661(以下MT 2.661)をapache2+mod_perl2上で動作させるまでに行った記録を記しておこうと思います。おそらく相当ニッチな要望だと思いますが(笑)。
コトの経緯を軽く説明しておきますと、MT 2.661はかなり古いCMSですが、このサイトのMT 2.661は自分の使い勝手がいいようにかなり改造を施してしまったので、なかなか最新バージョンに移ろうという気になれないでいました。そうこうしているうちにサーバーを最近立て替えたこともあり、以前のapache1.3 + mod_perl1.3環境から卒業してapache2+mod_perl2に対応する必要がてできました。その後MT自体は進化をとげメジャーバージョンが4になり、新しい環境にも標準で対応しているようなのですが、やはり使い慣れたMT 2.661を使い続けたい、だから移植しよう、というのがこの記事の動機となっています。
とりあえずapache1.3+mod_per1.3からapache2+mod_perl2にl変更するにあたってポイントとなる点は大きく2つに大別できると思います。
1つはapache2では並行動作のモードが複雑になった(従来のprefork動作以外にもmulti-thread動作等が選べる)ため、その上で動くmod_perl2がスクリプトを起動方法が変更になったようです。特にスクリプトを書く側にとって深刻な点は、起動時のディレクトリが必ずしもスクリプトの存在するディレクトリにならないことです。MT 2.661においても例外ではなく、MT 2.661では動作に必要となるサブモジュールの位置を、スクリプトが存在するディレクトリからの相対パスで求めているため、これは非常に大きな問題となります。先達はchdirでなんとか解決しようとされたり、apache2の構成方法にもよりますが従来どおりの動作が期待されるPrefork版のPerlハンドラを渡して解決しようとされたりしています(chdirが好ましくないことやPrefork版モジュールは本家mod_perl2のサイトで言及されています)。
もう一つの問題はmod_perl2でAPIの名前や動作がかなり変更されたことです。名前が変更されたことは書き換えで対応すればよいようで、これも先達によって『MT3.3をmod_perl2で動かすpatch(その1)』等で書き換え方法が公開されています。動作の変更点としては、MT 2.661で状態遷移を記録するために使用していたApache::Request::paramというものがありますが、Apache2::Request::paramでは変数を足すことができなくなった(『Apache2::Request PORTING from 1.X』参照)のが響いています。
以上2点を踏まえて、apache2+mod_perl2上でMT 2.661を動作するようにしました。変更点をまとめたdiffファイル(patchコマンドで適用可能形式)を公開するとともに、apache2+mod_perl2側の設定を以下に示します。
PerlSetEnv MTConfig /usr/local/share/web/MovableType/mt.cfg
Alias /mt/ "/where/to/mt/"
PerlModule ModPerl::Registry
PerlModule Apache::DBI
<Directory "/where/to/mt/">
<Files *.cgi>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
PerlSendHeader Off
</Files>
</Directory>
<Location /mt>
Options ExecCGI
Order Allow,Deny
Allow from all
</Location>
<Location /mt/db>
Order Deny,Allow
Deny from all
</Location>
1つ目の問題点、実行時のディレクトリの問題については環境変数渡し+@INCをスクリプト内で変更することでサブモジュールを見えるようにしました。@INCの変更はBEGINブロックで対応しないようにしましたが、これは『[perl]ModPerl::{PerlRun,Registry,RegistryPrefork}でのカレントディレクトリ、BEGINブロック、@INCの扱いメモ』に基づいています。
今回示した解決方法以外にも、試してはいませんがPerlOptions +Parent と PerlSwitches -I(mt/lib) 等を使った解決方法が考えられると思います。
2つ目の問題点は、先達の書き換え方法、並びにApache2::Requestに対して、paramが書き換え可能なApache2::RequestSubclassというラッパークラスを定義することで対応しました。このアイデアは『Apache2::Request::param で set / add できない』より戴きました。
問題点がでてきたら変更を考えていますが、以上の作業で現在のところ問題なく動作しています。
※ファイルのアップロードでこけることがありました。またしてもメソッド名が変更(size => upload_size、fh => upload_fh)になっていたようです。上記diffに追加してMT-2.661.CMS.pm.diffも mt/lib/MT/App/CMS.pm に対して適用してください。
トラックバックでBus Error (10)
久しぶりのサーバやサイトの管理をしてみました。Webサーバのバージョンをあげてみたりとか、リンク切れを修正してみたりとか、見た目的には何も変わらないので非常に報われない作業です。そんな中でWebサーバのエラーログを見たのですが、あまり見たくないエラーがありました。ありえない領域をアクセスした際に発生するBus Errorというエラーが。
そういえばここ1年くらいトラックバックがないなぁと思って調べてみると、どうやらトラックバックが送られてきたときにこのエラーが発生しているようです。
このサイトにもしトラックバックを送られていた方がいたら本当にごめんなさい。現在鋭意作業中ですが、また解決には至っていません。以下、その闘いの記録です。
※その後、strstr()の問題とわかり、mod_encodingのソースを修正することで解決しました。
症状
トラックバックが送られてくるとバスエラーでWebサーバのプロセスが落ちる。
エラーログを見ると
状況
現在このサイトはMacOSX(10.2.8 darwin 6.8)上でapache-1.3.36 + mod_perl-1.29 + libapreq-1.3等を使用し、CMSとしてMovableType 2.661で運営。MovableTypeはmod_perl上で動作中。
Apacheは
perlは
Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
Platform:
osname=darwin, osvers=6.6, archname=darwin
uname='darwin macintosh.local. 6.6 darwin kernel version 6.6: thu may 1 21:48:54 pdt 2003; root:xnuxnu-344.34.obj~1release_ppc power macintosh powerpc '
config_args='-de -Dprefix=/usr'
hint=recommended, useposix=true, d_sigaction=define
usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-pipe -fno-common -no-cpp-precomp -fno-strict-aliasing -I/usr/local/include',
optimize='-O3',
cppflags='-no-cpp-precomp -pipe -fno-common -no-cpp-precomp -fno-strict-aliasing -I/usr/local/include'
ccversion='', gccversion='3.1 20020420 (prerelease)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=4321
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=8
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -flat_namespace -L/usr/local/lib'
libpth=/usr/local/lib /usr/lib
libs=-lm -lc
perllibs=-lm -lc
libc=/usr/lib/libc.dylib, so=dylib, useshrplib=true, libperl=libperl.dylib
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dyld.xs, dlext=bundle, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags=' -flat_namespace -bundle -undefined suppress -L/usr/local/lib'
Characteristics of this binary (from libperl):
Compile-time options: USE_LARGE_FILES
Built under darwin
Compiled at Sep 20 2003 02:17:35
@INC:
/System/Library/Perl/darwin
/System/Library/Perl
/Library/Perl/darwin
/Library/Perl
/Library/Perl
/Network/Library/Perl/darwin
/Network/Library/Perl
/Network/Library/Perl
.
症状の分析
- mt-tb.cgiをPOSTメソッドで叩くと落ちる
- GETメソッドで叩くviewコマンド(以前のトラックバック情報を得る)やrssコマンド(RSSでトラックバック情報を取得)は落ちない
- トラックバックを送るのにmt-tb.cgiをGETで叩くと成功する。例えばmt_tb.cgi/(Trackback ID)?__mode=ping&title=hoge&url=hoge&excerpt=hoge&blog_name=hogeは成功する
- mod_perlを切ると問題なく動作
作業状況
- libapreqを最新バージョン(1.33)にあげてみようとするもmake testでコアを吐いてとまってしまうので断念(Apache::Test-1.28が悪い?)
- libapreq-1.3のCソース(c/apache_request.c)にデバックコードを挿入してみるも、デバックコードに到達する以前にBus Errorで落ちてしまっている
- libapreqのperl拡張の部分を現在調査中だがperlの拡張モジュールを読み書きした経験がないので困惑中
- 最新のperl-5.8.8にバージョンをあげることを考えるが、現行のバックアップ等を足ってからにしたいので未完
- Googleで調査してみるも同症状には出くわしていない
その後、コアファイル(/Library/Logs/CrashReporter/httpd.crash.log)を入手
OS Version: 10.2.8 (Build 6R73)
Host: Macintosh.local.
Command: httpd
PID: 9611
Exception: EXC_BAD_ACCESS (0x0001)
Codes: KERN_PROTECTION_FAILURE (0x0002) at 0x00000000
Thread 0 Crashed:
#0 0x900158d4 in strstr
#1 0x004843e0 in mod_enc_convert
#2 0x00098c8c in run_method
#3 0x00098f4c in ap_run_post_read_request
#4 0x000a2bd8 in ap_read_request
#5 0x0007d82c in child_main
#6 0x0007db80 in make_child
#7 0x0007e07c in perform_idle_server_maintenance
#8 0x0007e91c in standalone_main
#9 0x0007f1f0 in main
#10 0x000026a0 in _start
#11 0x00002520 in start
PPC Thread State:
srr0: 0x900158d4 srr1: 0x0000f030 vrsave: 0x00000000
xer: 0x00000000 lr: 0x900158d0 ctr: 0x90000e40 mq: 0x00000000
r0: 0x900158d0 r1: 0xbffff680 r2: 0x312e3100 r3: 0x00000007
r4: 0x80808080 r5: 0x00000000 r6: 0x80808080 r7: 0x00000000
r8: 0x00000000 r9: 0x00486a55 r10: 0x900e161c r11: 0xa0004318
r12: 0x90000e40 r13: 0x00000000 r14: 0x00000000 r15: 0x00000000
r16: 0x00000000 r17: 0x00000000 r18: 0x00000000 r19: 0x00000000
r20: 0x00000000 r21: 0x00000000 r22: 0x00000000 r23: 0x00000000
r24: 0x00000000 r25: 0x00000000 r26: 0xbffffddc r27: 0x00000007
r28: 0x00000057 r29: 0x00486a55 r30: 0x00000000 r31: 0x00484308
思惑が完全に外れていたようです。mod_davを導入するためにmod_encodingを入れていたのですが、その中のstrstr()関数で落ちているようです。見てみたところ、NULLチェックができていないのが原因のようでした。
mod_encoding.cの484行目付近
const char *userAgent = ap_table_get(r->headers_in, "User-Agent");
if (strstr(userAgent, "WebDAVFS")) {
hfsClient = 1;
}
を以下のように修正
const char *userAgent = ap_table_get(r->headers_in, "User-Agent");
if (userAgent && strstr(userAgent, "WebDAVFS")) {
hfsClient = 1;
}
英語コメントスパムへの対処
今までコメントスパムの対処方法として『HTMLタグを徹底的に認めない』や『禁止IPに登録されたのをわからなくする』、『MD5等を使ってコメント欄を偽装する(こちらは記事にしていません)』などを行ってきましたが、先日等々大量の英語スパムに見回れました。仕方がないので、英語スパムを駆除する方法を考えることにしました。
方法としては、日本語の文字が入っていないものをはじく方法を採用することにしました。特定の人が投稿できなくなる可能性があることに抵抗があったため、今までやらなかったのですが、とうとう諦めることにしました。
どうやらこの手の対策はプラグインでできるようですが、それらのプラグインはMovableType 3を要求しているようです。このサイトは未だにMovableType 2.661で運営されているので、動作するかわかりません。
そこで、いつものことながらソースをハックします。
Perlには日本語モジュールのJcodeというものがあり、それを使用してコメントに日本語が含まれているかどうか判断することができます。
my $str_encoding = getcode($str);
そこで以下の改造をしました。
/path/to/MT/lib/MT/App/Comments.pm(MT2.661だと162行目付近)に追加
my $comment_encoding = getcode($q->param('text'));
if ($comment_encoding eq 'ascii') {
return $app->redirect($entry->permalink);
}
これで英語コメントを無条件にはじけます。
Trackback SPAMがやってきた
最近トラックバックスパムがめちゃくちゃ来まくっています。最終的にはコメントスパムのときと同じようにソースを改変(うちはこんなやり方をしています、効果絶大)することによって解決をはかりたいと思っていますが、なかなかよいアイデアが思いつきません。とりあえず巷にはコメントと同じように、連続投稿を禁止するパッチはあるようなのでそれをしましたが、それだけでは納得がいかないので、一時的にmt-tb.cgiを使えない状態にしました。従って現在Trackback、ならびにTrackbackされたURLへ飛ぶことが出来なくなっています。ご不便をおかけします。(→2/13、対策を施し復活させました。)
何かよい方法をご存知でしたらご一報ください(そろそろベイジアンフィルタも検討しますか!?)。
このトラックバックスパムというのは今回がはじめてきたのですが、どうやらコメントスパムと同じ系統のようですね。問題のスパムのタイトルは『online casino』やらで、これは今まできたことのあるコメントスパムのタイトルと一致します。1時間に200回近くTrackback pingしてきました。Trackbackを受信するごとにリビルドする関係上、スパムというよりかDoS攻撃のような感じです。かなり頭にきています…。
とりあえず、コメントスパムと違ってトラックバックスパムはMovable Typeの管理画面から直接的に消すことができないので大変ですがデータベースをいじれば簡単に大量に消すことが可能です(データベースを直にいじることは危険をともないます、自信がない場合はお勧めできませんし、またここに書いてある方法を行うことも自己責任で願います)。
うちはデータベースにPostgreSQLを使用しているのですが、その場合はPostgresの会話型UIのpsqlを用いて以下のように操作をすることで消すことが出来ます。以下、mt.cfgで指定したデータベース名がmtDB、データベースアカウント名がmtdbuserだとして説明します。
(ログイン、以下mtDBではじまる行が入力行です)
mtDB=> ¥dt
# データベースのテーブル一覧が表示される、その中のmt_tbpingにトラックバックされた情報が詰まっている
mtDB=> SELECT * FROM mt_tbping;
# これでトラックバックされた情報の一覧をみることができる
mtDB=> DELETE FROM mt_tbping WHERE tbping_id = 100;
# 例えばIDが100のトラックバックを消してみる、IDとは上のSELECT文で一番左に表示された数字
mtDB=> DELETE FROM mt_tbping WHERE tbping_id >= 101;
# 例2、IDが101以降のトラックバックを消してみる
mtDB=> ¥q
# psqlを終了する
この後管理画面でリビルドをすれば反映されます。
コメントスパム根絶?
ある対策をしてからコメントスパムがまったく来なくなりました。というかはじき返しているみたいです。 その対策とは単純でHTMLタグをコメントとして認めない、ただそれだけです。ただしやるからには方法は徹
禁止IPに指定したことを知られないように
どうやら先日のコメントスパム対策はある程度功を奏しているようですが、スパムを送ってくる側が対応するのも時間の問題だと思います。ということで、今回は最終手段である禁止IPリストへの登録について考えてみま
コメントスパム対策
コメントスパム対策をしました。一日に十数件もくるコメントスパムを消す時間が惜しいくらい忙しいので…。 導入した方法はオリジナルだと思います。コメントを投稿するフィールド名を変えてしまいました。しかも
MTのCreative Commonsを2.0に
MovableTypeでは標準でCreative Commonsという著作権明示の為のの機能がついてきますが、MT2.6系で採用されているライセンスはバージョンが古く、部分的に廃止されたバージョン1.
テンプレート共通化とJavaScriptによる軽量化
様々なサイトをみていますと、テンプレートの共通化とPHPによるインクルードを使用してMovableTypeの軽量化を実現されている方が多いようですね。このサイトでも色々と工夫をしてMovableTyp
MTElse問題
MovableTypeで、もともと組み込み済みのMTIf系の条件タグを使うと、それと組み合わせでMTElseというのが使えますよね。でも、自前でつくったプラグインの条件タグはこのMTElseがうまく作
RSS 2.0 Now Available
気が向いたので、サイトの細かい部分をいじっていたところ、いままでRSS1.0しかダウンロードできる状態にしていなかったみたいです。そこで、RSS2.0を使用可能にしました。上のアイコンからも落とせま
offsetだけでは駄目なわけ
カテゴリのテンプレートをいじっていて気になったことが。最新5件のエントリーは全文表示して、残りのエントリーは概要だけにしよう、と思って以下のようなコードを書きました。 (全文を表示する) (概
コメントスパムがやってきた
泣きそうです。コメントスパムが100個くらいきました。がんばって消去しました。 でも、がんばり方にも工夫があったようです。メニューのテンプレートを変更してコメントを消しやすくする方法。Memo Lea
TrackBack機能付き掲示板(作成中)
TrackBack機能付きの掲示板を現在開発中です。8割がた完成しているのですが、以下の点で悩んでいます。 やたらめったら他の方のブログにもトラックバックできてよいものか?自分のブログ内にトラックバッ
JavaScriptでリンクの除去
MovableTypeのコメントで『URLを自動的にリンクにする』を選択していると、コメントの概要表示をしようとするときにこのリンクが邪魔でうまくいかないことがあります。 この場合の対処方法として、M
ブログのすばらしさに感動
今、すごくブログというシステムのすばらしさに感動しています。 昨日プラグイン作成の邦訳を載せたわけですが、こんなにも反響があるとは。しかも間違いを指摘してくださる方までいたりして本当に感謝感激していま
MovableTypeのプラグイン作成(邦訳)
MovableTypeのプラグインを作成したくなったので、参考資料を邦訳してみることにしました。元の文はDeveloping Movable Type Plug-insでオライリーの記事です。 えぃ
NetPBMでpngのサポートを
どうやらMovableTypeのサムネイル画像の作成をNetPBMでやっていると、デフォルトではpng画像ファイルがサポートされていないみたいです。(ImageMagickじゃなくNetPBMを使うや
管理画面のSSL化
このサイトを参考にMovableTypeの管理画面をSSL化(通信経路の暗号化)してみました。が、このサイトのmt.cfgの方法だと、通常のコメントやトラックバックまでSSL化されて、見てくれている人
NetPBM
ImageMagick(PerlMagick)に敗北したままなのですが、なんとか画像のサムネイルを使いたいと思っていたところ、ImageMagickのかわりにNetPBMというツールが使用できるような
MovableTypeで生HTML
MovableTypeでHTMLをそのまま出力したいときにはどうすればいいか??ということを最近考えていろいろためしています。文章の再利用性が下がるのはいやなので、HTMLのコードを生の文章として出力
Monthly Archiveのカレンダー
Monthly Archiveの使い勝手を向上させるために、Monthly ArchiveをJavaScriptが出力するカレンダーから切り離し(JavScriptがこのサイトでどのように使われている
JavaScriptで軽量化を!!
このサイトはMovableTypeというCMS(Contents Management System)を使って運用しているわけですが、CMSを使ったサイト運用に求められるものはなにかっつうのを探求して
Macroプラグイン
Macroプラグイン入れてみました。それほど重要でもない文章でも再利用性がないというのは、ちょっといやだからね。いれたプラグインはMTMacroです。以下テストとして使用してみますだ。 HOGE 上
mod_perlで高速化
MovableTypeが遅い(なぜならServerはPower Mac G3 B&H 350MHz)!!と感じたので、高速化を決意。 いろいろ調べてみたら、mod_perl用に動かすと結構高速化できる
MovableTypeでGoogleってみた
MovbaleType(このページで使っているサイト管理システム)をキーワードにして検索してみると結構いろんな情報がでてくるなぁ。 で、おもしろかったのが MovableType For i-mod