毎秒1000リクエスト を捌く超高速CMS「adiary」
2008/02/28(木)Re: adiary v1.44のサムネイル周りがbuggyな件
eggshell blue のadiary v1.44のサムネイル周りがbuggyな件への返信です。
分かりやすく箇条書きにします。
- Windows に ImageMagick を入れるのは若干コツが入ります。(参照)
- adiary Ver2.00β1のせりかのアルバム機能はオフにできます(←加筆した)。*1
- adiary Ver2.00β1では画像アップロードdirはadiary.confのものをすべて引き継ぐようになりました。
- ".jpg"を付加するのは単純にサムネイル画像がjpegだから。
××の部分がどこにあるか分からないとかでしたら、遠慮無くMLかコメントあたりで聞いて頂ければ(時間差はありますが)答えますので、お気軽にどうぞ。
あと改変方法がプログラムの仕様に対して的確でびっくりしました。Ver2.00β1で画像アップロードdirをadiary.conf.cgiから指定可能にしたのとまったく同じ実装です(^^
余談返し
日記中の自サイト内アップロードフォルダに存在するファイルのみの情報を抽出し、日記の変更前後で差分取ってやって無くなってるファイルだけを抜き出せば自動削除機能できるんじゃね?
複数の日記から同一画像を参照しているケースだけちょっと困りますが……チェックボックスでも付けておけばいいのか。
2008/02/17(日)adiary Version2.00β1公開情報
本バージョンはβバージョンです。β版の間Ver2.00正式版へ向け様々な改変が予定されているため、時にアップデート手順が煩雑になることも想定されます(*.confの書き直し等)。それでも構わない、または、βテストにご協力頂ける方のみインストールをしてください。*1
なおadiary本体のライセンスが GPLv2 から AGPLv3 に変更になっています。MySQL利用時は「GPLv2 or laterのMySQL」でお使いください。
Ver1.44→Ver2.00β1(=Ver1.991表記)の変更点
- せりかのアルバム機能を adiary 本体に取り込みました。
- はてなスターの仕様変更に対応しました。
- 月別表示も、一覧表示ができるようになりました。
- 日記の紹介での改行を有効にしました。
- 日記帳一覧に、最新タイトル表示モードを付けました(こんなの)。
- 同一ブログ内トラックバックを、最近のトラックバック欄に表示しないようにしました。
- 【記法】リンク時の target/class/rel をすべて指定できるようになりました(日記帳の詳細設定→パーサー設定)。*2
- 【変更】サイドバーの「RSS, LIRS, hina-di」のリンクを削除しました。
- 【変更】ほぼ利用実績のないLIRS/hina-di向けアンテナ情報を生成しないよう変更しました。
- 【変更】親記事へのリンクを記事下部に出力するようにしました。
- 【変更】画像サムネイルディレクトリ名を thumbnail/ から .thumbnail/ に変更しました。
- 【変更】Google Analytics使用時のトラッキングコードを最新仕様(ga.js)に変更しました。
- 【パス自動認識】cgiファイル名の取得方法を「$ENV{SCRIPT_NAME}」からcgi起動時のパスに変更しました。
- 【fix】一般ユーザーに対して日記帳の一覧を表示させない設定にしていても、携帯用画面などから表示出来てしまう不具合を修正しました。
- 【fix】メール投稿時の拡張子チェックで、小文字拡張子決めうちだった点(大文字拡張子だと投稿できない問題)を修正しました。
- 【fix】はてなスターがつけられない問題を修正しました。(Thanks to ひとぅ)
- 【fix】印刷用の表示で画像か表示されない不具合を修正しました。([ml:users:162:Thanks to 小沼])
- 【fix】IE使用時「URLの自動リンク」の設定が無効になっていた不具合を修正しました。(Thanks to 浅野)
- 【fix】埋め込みテキスト編集で、<@s.bodyend_1st>の設定値が展開されて保存される不具合を修正しました。(Thanks to 浅野)
- 【fix】カテゴリのソート設定が無効になっていた不具合を修正しました。(Thanks to 浅野)
- 【fix】引用記法を入れ子した際、外側に引用元アドレスを書くと期待通り動かないバグを修正。
- 【fix】日記帳の再構築に失敗した記事が表示されない不具合を修正。
- 【fix】子カテゴリの記事がすべて非表示のとき、開く記号「▼」が表示されてしまう不具合を修正。 (Thanks to serika)
- 【fix】コメントが付いた直後に生成されるRSSで「続きを読む」を無視し全文が配信されるバグを修正しました。(Thanks to ぷら)
- 【fix】別配信RSSの配信情報がmetaタグとして出力されない不具合を修正しました。
- 【変更】デフォルトのユーザー名の長さ制限を30byteに緩和しました。(Thanks to スポック)
- 【テーマ関連】
- sumomoテーマで日付の表示がオフであった不具合を修正しました。
- 親記事へのリンクのHTML出力位置を変更し、デフォルトfloatをオフにしました。
- 【携帯関連】
- 【fix】メール投稿アドレス設定時、2重に登録した場合、2つの登録が消える問題を修正しました。*3
- 【fix】mod_rewrite 利用時、記事中画像/アイコン画像が表示されない不具合を修正。
- 【fix】メール投稿のヘッダ解析で、"multipart"検索時に小文字固定だった問題を修正しました。(Thanks to スポック)
- 【fix】携帯表示から検索できなくなっていた不具合(Ver1.4x~)を修正しました。(Thanks to スポック)
- 【fix】携帯表示における<$v.phone_sjis>時のQuery処理の問題を修正しました。(Thanks to スポック)
- 【fix】メール投稿時、一部機種で画像添付が認識されない不具合を修正しました。([ml:users:181:Thanks to 小沼])
- 【fix】メール投稿時、長い日本語タイトルを入力すると途中に空白が入る問題を修正しました。(Thanks to 人柱a)
- ほか多数スポックさんにご指摘頂きました(多謝)。
- 【fix】UTF-8環境で運用時、閲覧者がFirefox等を利用したとき複数のテーマにおいてページ送りの"≪"が文字化けする問題に対処しました。*4
- 【fix】【SpeedyCGI】base*.pm の書き換えの自動リロードができない問題を修正しました。
- その他、雑多な修正。(うち複数は浅野さんのご指摘)
Version1.44以前(C73/2.00α含む)からの乗り換え
- 上書きしたのちに、adiary.conf.cgi/uploader.conf.cgi/mail.conf.cgi をあたらしいサンプルから作り直してください。
- 管理者権限でログイン。システム管理 → 管理者メニュー → Ver2.00β1への移行処理を行ってください。
- wikiモードで親子コンテンツを作成している方は「日記帳を再構築」してください。
Version1.32以前からの乗り換え
Version1.40への移行処理を先に行ってください。
アルバム機能を使いたくない場合
adiary.conf.cgiを次のように変更してください。
# JavaScript使用時のアップローダ <$v.image_js_uploader_url = "uploader.cgi/%i/%Y%m?simple"> # 画像アルバムとしてリンク/公開時のURL(コメントアウト) #<$v.image_album_url = "uploader.cgi/%i">
後のバージョンでは、簡単に設定できるように .conf.cgi のデフォルトを変更しておきます。
既知の問題
- アルバムシステム使用時、ゴミ箱内でファイル操作を行うとtrashboxというディレクトリが作られる。
- PostgreSQL/MySQL利用時、外部からのトラックバックを受け付けても最近のトラックバックリストに反映されない。
- 単一記事表示時に記事全体を閉じるスイッチ「▼」が使用できない。
- 任意の日記帳を作成したとき、その日記帳に対してメール投稿が失敗する。(diary_write / エラーコード25)
2008/02/05(火)skltonシステムで再帰関数
最近書いた、adiary関連のとあるskeltonで必要に迫られて再帰関数を作りました。
再帰関数なスケルトン
<@local(ary, subdir, prefix, depth, header, idx, x)> <@>再帰サブルーチン -------------------------------------------- <$sub = begin)> <$subdir = argv#1> <$prefix = argv#2> <$depth = argv#3> <$header = if(depth, '<img width=' . (9*depth) . #' height="9" src="<@Basepath><@v.album_icons>spacer.gif">')> <$idx = 0> <@forexec(t, argv#0, begin)> <$push(dirlist, t)> <$ary = v.search_folderlist(basedir, t.path, t.pathname)> <$uri_encode(x = t.path)><@>URIエンコード済パス / ""内に書いても安全にする <@ifexec(ary#0, begin, begin)> <@header><a href="#" onClick="return toggleBlock('<@prefix><@idx>');"> <img src="<@Basepath><@v.album_icons>minus.png" id="img_<@prefix><@idx>"></a> -<a href="<@v.myself2><@x>"><@t.name></a><br> <div id="blk_<@prefix><@idx>"."_"> <@exec(sub, ary, "<@t.path>", "<@prefix><@idx>_", depth+1)> </div> <$else> <@header>+-<a href="<@v.myself2><@x>"><@t.name></a><br> <$end> <$idx+=1> <$end> <$end> <@>main --------------------------------------------------------- <$dirlist = argv#0> <$basedir = v.user_dir> <@exec(sub, v.search_folderlist(v.user_dir), "", "blk_", 0)>
ローカル変数宣言に再起関数。ここまでくるとすでにスケルトンではないような気もしますが、viewに関連する部分はプログラム本体には入れたくないので、こんな感じです。
このとおり Satsuki-system はかなり強力ですが、もう少し記述能力をアップさせたいところではあります。
<@x=forexec(t, v.load_folderlist(), begin)>
とかできませんし、ローカル変数宣言もファイル全体に対する宣言となっているにも関わらず、実装は関数単位分離になるため、かなり理解しにくいところがあります。*1
スケルトンの実行コード
ついでに。このスケルトンは次のような実行コード(Perl)にコンパイルされた後、__cache/ ディレクトリ以下に保存されます。
sub { my $Out = shift; my $R = shift; my $Ary = shift; my $v = $R->{v}; $_[1] = \$v; my ($x,$idx,$depth,$header,$prefix,$subdir,$ary); $R->{sub} = $Ary->[1]; $R->{dirlist} = $R->{argv}->[0]; $R->{basedir} = $v->{user_dir}; $_[0]=38; push(@$Out, $R->exec($R->{sub},$v->search_folderlist($v->{user_dir}),"","blk_",0)); $R->{Break} && return; return; } sub { my $Out = shift; my $R = shift; my $Ary = shift; my $v = $R->{v}; $_[1] = \$v; my ($x,$idx,$depth,$header,$prefix,$subdir,$ary); my $subdir = $R->{argv}->[1]; my $prefix = $R->{argv}->[2]; my $depth = $R->{argv}->[3]; my $header = ($depth != 0 && (('<img width=' . (9 * $depth)) . " height=\"9\" src=\"$R->{Basepath}$v->{album_icons}spacer.gif\">")); my $idx = 0; my $X=$R->{argv}->[0]; if (ref($X) ne 'ARRAY') { $X=[]; $R->error_from("line 17 at $R->{__src_file}", '[executor] forexec: data is not array'); }; foreach(@{ $X }) { $R->{t}=$_; $_[0]=18; push(@{$R->{dirlist}},$R->{t}); $_[0]=19; my $ary = $v->search_folderlist($R->{basedir},$R->{t}->{path},$R->{t}->{pathname}); $R->{Break} && return; $_[0]=20; $R->uri_encode(($x = $R->{t}->{path})); $R->{Break} && return; if ($ary->[0]) { push(@$Out, $header); push(@$Out, '<a href="#" onClick="return toggleBlock(\''); push(@$Out, $prefix); push(@$Out, $idx); push(@$Out, '\');"><img src="'); push(@$Out, $R->{Basepath}); push(@$Out, $v->{album_icons}); push(@$Out, 'minus.png" id="img_'); push(@$Out, $prefix); push(@$Out, $idx); push(@$Out, '"></a>-<a href="'); push(@$Out, $v->{myself2}); push(@$Out, $x); push(@$Out, '">'); push(@$Out, $R->{t}->{name}); push(@$Out, '</a><br> <div id="blk_'); push(@$Out, $prefix); push(@$Out, $idx); push(@$Out, '_"> '); $_[0]=24; push(@$Out, $R->exec($R->{sub},$ary,"$R->{t}->{path}",("$prefix$idx" . "_"),($depth + 1))); $R->{Break} && return; push(@$Out, '</div> '); } else { push(@$Out, $header); push(@$Out, '+-<a href="'); push(@$Out, $v->{myself2}); push(@$Out, $x); push(@$Out, '">'); push(@$Out, $R->{t}->{name}); push(@$Out, '</a><br> '); } $idx += 1; } return; }
これはコンパイルログディレクトリ <$Compile_log_dir="xxx"> を設定することで誰でもみることが出来ます。*2
なお出力を文字列連結せずスタックに積んでいくのは、高速化のためです。(コンパイラが)無駄に綺麗なソースを出力するのは単なる趣味です(笑)