Archive for the ‘program’ Category

mixiにそのまま投稿しちゃうと、本来リンクじゃないと困るものが、ただのテキストになってしまうわけで。どっちみち携帯から見てる人には無用なエントリになっちゃうし、いっそのことmixiには投稿しないようにしようと。一番てっとり早いのはP::P::MixiDiary.pm内で、単純にif文でほげほげすることなんだけど。ちょっと気が向いたのでplugin初挑戦してみた。

package Plagger::Plugin::Filter::StripDeliciousDailyPost;
use strict;
use base qw( Plagger::Plugin );

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'update.entry.fixup' => \&filter,
    );
}

sub filter {
    my($self, $context, $args) = @_;

    my $title = $args->{entry}->title;
    for my $entry ($args->{feed}->entries) {
        if ($entry->title =~ /^links for \d{4}-\d{2}-\d{2}$/i) {
            $context->log(info => "Delete Delicious daily post entry " . $entry->link);
            $args->{feed}->delete_entry($entry);
        }
    }
}

1;
__END__

やはりperlは書き慣れんな。yamlを以下のようにして動作確認。

plugins:
  - module: Subscription::Config
    config:
      feed:
        - url: http://nobu666.com/rss?feed=rss2
  - module: Filter::Rule
    rule:
      module: Deduped
      path: /tmp/blog2mixi.tmp
      compare_body: 1
  - module: Filter::Reverse
  - module: Filter::FindEnclosures
  - module: Filter::FetchEnclosure
    config:
      dir: /tmp/fetch-image
  - module: Filter::FormatText
  - module: Filter::EntryFullText
  - module: Filter::StripDeliciousDailyPost
  - module: Publish::MixiDiary
    config:
      username: メールアドレス
      password: パスワード
      interval: 10
      originally_link: 1

,

前回のwordpressのformatterがキモいタグを生成するので、どうにかするはME2.2.3以外でpatchすると、管理画面で激しくwarningが出てエライことになる。ので、v2.3.3用のpatch。


--- www/wp-includes/formatting.php.orig Thu Feb 28 16:37:29 2008
+++ www/wp-includes/formatting.php Thu Feb 28 16:39:27 2008
@@ -63,7 +63,7 @@
$pee = $pee . "\n"; // just to make things a little easier, pad the end
$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
// Space things out a little
- $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
+ $allblocks = '(?:code|table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
@@ -88,6 +88,10 @@
if (strpos($pee, '<pre') !== false)
$pee = preg_replace_callback('!(<pre.*?>)(.*?)</pre>!is', 'clean_pre', $pee );
$pee = preg_replace( "|\n</p>$|", '</p>', $pee );
+ $pee = preg_replace('| {4}|', str_repeat(' ',4), $pee);
+ $pee = str_replace('\\', '\\\\', $pee);
+ $pee = preg_replace('|<code>.*?</code>|se', "str_replace(array('<p>', '</p>'), array('', '<br /><br />'), '$0')", $pee);
+ $pee = StripSlashes($pee);

return $pee;
}

, ,

<p></code></p>とかいう謎タグが生成されて激しく気持ち悪いので、phpに手を入れる。As You Like It » Blog Archive » WordPressのエディタとの付き合い方を参照して、その通りに書き換えるだけ。patchにしとく。


--- formatting.php.org Fri Feb 22 18:23:52 2008
+++ formatting.php Fri Feb 22 18:21:16 2008
@@ -55,7 +55,7 @@
$pee = $pee . "\n"; // just to make things a little easier, pad the end
$pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
// Space things out a little
- $allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
+ $allblocks = '(?:code|table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)';
$pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
$pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
$pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
@@ -80,6 +80,13 @@
if (strpos($pee, '<pre') !== false)
$pee = preg_replace('!(<pre.*?>)(.*?)</pre>!ise', " stripslashes('$1') . stripslashes(clean_pre('$2')) . '</pre>' ", $pee);
$pee = preg_replace( "|\n</p>$|", '</p>', $pee );
+ $pee = preg_replace('| {4}|', str_repeat('&nbsp;',4), $pee);
+ $pee = str_replace('\\', '\\\\', $pee);
+ $pee = preg_replace(
+ '|<code>.*?</code>|se'
+ , "str_replace(array('<p>', '</p>'), array('', '<br /><br />'), '$0')"
+ , $pee);
+ $pee = StripSlashes($pee);

return $pee;
}

, ,

5.0からHEAPテーブルでも可変長レコードがサポートされたのだが(BLOBとTEXTは未サポート)、VARCHARでフィールド作っても固定でメモリを食われている気がする…まだちゃんと調べてないけど。

とりあえず、MySQLのデフォルト文字コードをUTF-8にしている場合、HEAPテーブルを使う際には注意が必要だと言うことはわかった。注意が必要って言うか、要はテーブルとフィールドのデフォルト文字コードに気をつけようって言うだけ。日本語を扱わないのであれば、UTF-8のまま使っているとメモリをかなり喰う。30バイト以内のランダムな文字列 + URL、っていうテーブルをHEAPで使っていたのだが、最初はテーブルの定義をVARCHAR(100) + VARCHAR(2048)とかにしていたら、show table statusするとAvg_row_lengthが5kとかになっていた。それをVARCHAR(30) + VARCHAR(512)に変えると2kくらいに減少。ALTER TABLEでテーブルとフィールドの文字コードをUTF-8からASCIIに変えてあげたら550バイトくらいまで小さくなった。やっぱ日本語が絶対に入らないとわかっているのなら、UTF-8を使うのはメモリ(ディスク)の無駄だ。拡張性はあるんだけど、URLとかidとかはASCIIで済むのだから。

, , , ,

Development Environment Conferenceに会社の先輩と二人で行ってきた。12:00に受付開始して12:03で定員に達したとか…俺の受付は12:02だったのでギリだったのかも知れないな。

っていうか受付とか特に何もなくて、紙を2枚もらうだけ。早めに行ったりしてたら、申し込みしてなくても潜り込めたんじゃないのかね…。とは言っても席に余裕がなかったのでアレだが。申し込み時のメールアドレスくらいは聞かれるかと思っていたのだが。

スピーカー陣が超豪華だったのだが、一番のお目当てはma.la氏萌ディタ話。開発環境の話なのでしないはずがないと踏んでいたのだが、案の定してくれました。変態過ぎる環境で仕事をしておられる様子で、大変素敵です。他の方もスピーチ内容は大体予想通りで、emacsとかvimとかscreenとかsvkとか。

以下メモ。

はてなと私の開発環境 : 伊藤直也氏

  • zsh+screen+emacs
    • bashは小学生まで
    • /u/l/b/p が /usr/local/bin/perl に展開されたりするよ
  • subversion
    • cvsは小学生まで
  • server.pl
  • perlsh

zshそんなに便利なのか。俺は小学生なのでbashだが。emacsは使いたくないがzshは試そうかな。emacsってデフォルトのキーバインドが変態過ぎて覚える気にならないのよね…しかも大体vimでも同じコトできたりするし。screenは基本すぎるので割愛。

Agile Web Development with 萌ディタ Reloaded : ma.la氏

  • ハード
    • 20inchワイド縦置きデュアル
    • HHKLite2
    • トラックボール
    • ショートカットキー専用キーボード
  • ソフト
    • 萌ディタ / bluewind / AutoHotKey / 窓使いの憂鬱
  • RubyはWEBrick動かすためにある
  • それWEBrickでできるよ、WEBrickでどうやるかは訊いてねぇよ、というやりとりがしたい
  • それAutoHotKeyで(以下略
  • window.statusデバッグ / document.titleデバッグ
  • DebugScreen自分で作ったけど使ってない
  • IEの気持ちがわかればalertで十分
  • livedoorは技術者を募集しています

萌ディタは自分も開発追っかけて使ってたなぁ。久しぶりにサイト見に行ったら経過報告みたいな文章がアップされててビックリした。いつアップしたのか知らないけど…作者さん死んではいなかったのねw

Windows Environment & Vim : secondlife氏

  • Windowsスキー && ゲイツスキー
  • fub
    • migemoが標準で
  • 窓使いの憂鬱 / bluewind / Avesta / Eijiro / シフトムーブ / kbdacc / migemize explorer / Alt-Tab Replacement / htmlhelp
  • Vimは至高のエディタである
    • 移動は/?*#
    • 最短手順よりも思考速度と手順のバランスで自分にマッチする手順で
      • 5wとかしないでwwwwwってやる
    • httpとかscpとかスキームも開ける
    • C-a, C-xで数値のインクリメント・デクリメント
    • earlier, laterで時間軸でのundo, redo
  • dotfileはsubversionで管理してsymlink

scp開けるとか、C-aとかC-xとか知らなかった。text-objectsはなんかさっぱりわからず。難しいよ…

Binary Hacks in Action : 高林哲氏

  • straceとかgdbの基本的な話
  • ソースがなくてもバイナリを直接編集
    • 文字列を短くするのは簡単だけど、長くするのは難しい
      • ライブドアをはてなにするのは簡単だけど、はてなをライブドアにするのは難しいよ
  • Binary Hacksが10月にオライリーから出版されるよ

Cやってる(やってた)人には割と当たり前な話だった。ていうか開発環境の話じゃないしw あ、Binary Hacksは出たら買います…

Vox/Plaggerの裏側見せます : 宮川達彦氏

  • Consolasフォントいいよ
  • dotfileはsubversionとsymlink
  • Vox
    • Zen+CentOSで1人ずつバーチャルな環境を持ってる
    • アプリのインフラはrpmで
  • Plagger
    • IRCとTrac
    • Test::Base
    • DRY
    • svk
  • CPAN mini
    • 最新版だけローカルにミラーしておく
  • 飛行機の中暇だからwikipediaもローカルに置きたい
  • Aliasでtypoをフォロー

Consolasは是非試す。よさげ。svkもsmerge?試そう。svnのマージはうざい。

オレポータビリティ : 青木峰朗氏

  • ヒューマンインターフェースには金をかけたいので良い椅子(でもマウスは\1500)
  • フルキーボードのテンキーは、使わないのでノコギリで切った
  • 様々なプラットフォーム、様々なOSで計20台が置いてある
  • 極力ソフトはインストールしない、カスタマイズしない
    • Ruby, Cコンパイラ, zsh, 素のvi, CVS
  • ホームは /usr に合わせて全マシン共通にする
    • ツールの作成が楽になる

一杯マシンあったけどSGIはなかったな…

終わったときにはもう22時近かったのでそのまま退散。懇親会とか行きたかったけど(あったのかどうかすら知りませんが)、帰れなくなるので…。しかも晩飯食う時間がなかったので死にそうだった。とはいいつつ、せっかくだから名刺交換くらいしておけば良かったな。

, , , , ,

otsuneさんのはてなダイアリーを購読してるとPlaggerがこける件、http://plagger.org/trac/changeset/1672修正されていました。単にnullチェック漏れだったっぽい。

,

なんかgmailが寂しいと思ったので、LogLevelをdebugにして動かしてみたら以下のようになった。


Plagger::Plugin::Subscription::LivedoorReader [info] You have 614 unread item(s) on livedoor Reader.
Plagger [info] plugin Plagger::Plugin::Aggregator::Simple loaded.
Plagger::Plugin::Subscription::LivedoorReader [debug] Logging in to Livedoor Reader
Plagger::Plugin::Subscription::LivedoorReader [debug] get unread items of 1967834
Plagger::Plugin::Subscription::LivedoorReader [debug] get unread items of 2023794
The 'epoch' parameter (undef) to DateTime::from_epoch was an 'undef', which is not one of the allowed types: scalar
at /home/nobu666/perl/lib/site_perl/5.8.8/i386-freebsd/DateTime.pm line 430
DateTime::from_epoch('undef', 'epoch', 'undef', 'time_zone', 'local') called at /home/nobu666/perl/lib/site_perl/5.8.8/Plagger/Date.pm line 63
Plagger::Date::from_epoch('Plagger::Date', 'undef') called at /home/nobu666/perl/lib/site_perl/5.8.8/Plagger/Plugin/Subscription/LivedoorReader.pm line 97
Plagger::Plugin::Subscription::LivedoorReader::sync('Plagger::Plugin::Subscription::LivedoorReader=HASH(0x8a3d72c)', 'Plagger=HASH(0x87b4d44)', 'HASH(0x901eae0)') called at /home/nobu666/perl/lib/site_perl/5.8.8/Plagger/Plugin/Subscription/LivedoorReader.pm line 58
Plagger::Plugin::Subscription::LivedoorReader::__ANON__('Plagger=HASH(0x87b4d44)', 'HASH(0x901eae0)') called at /home/nobu666/perl/lib/site_perl/5.8.8/Plagger.pm line 328
Plagger::run('Plagger=HASH(0x87b4d44)') called at /home/nobu666/perl/lib/site_perl/5.8.8/Plagger.pm line 69
Plagger::bootstrap('Plagger', 'config', '/home/nobu666/plagger/ldr2gmail.yaml') called at /home/nobu666/perl/bin/plagger line 24

日付絡みで落ちているっぽい?2023794はsubscription_idっぽいので、LDRのAPIを http://reader.livedoor.com/api/all?subscribe_id=?2023794 こんな感じで叩いてみた。返ってきたJSON抜粋。


{"ads":[{"url":"http://www.gyao.jp/rss/","title":"完全無料パソコンテレビ「GyaO」","description":"番組情報をジャンル別にRSS配信。新着情報をチェックすれば見逃しも防げる!"},{"url":"http://blog.livedoor.com/cgm.html","title":"ライブドアのブログ・クチコミ","description":"ウィキ、ソーシャルブックマーク、SNS、写真共有、キーワードすべてあります!"}],"subscribe_id":"?2023794","channel":{"error_count":"0","link":"http://d.hatena.ne.jp/otsune/","description":"import otsune from Hatena","image":null,"title":"import otsune from Hatena","feedlink":"http://d.hatena.ne.jp/otsune/rss","subscribers_count":"178","expires":1156265399},"items":[{"enclosure":null,"link":"http://d.hatena.ne.jp/otsune/99990101/p1","enclosure_type":null,"author":"otsune","body":"","created_on":null,"modified_on":null,"id":"554908","title":"いそいで口で吸え","category":""},{"enclosure":null,"link":"http://d.hatena.ne.jp/otsune/20060821/AsyncMedia","enclosure_type":null,"author":"otsune","body":"\n\t\t<div>\n\t\t\t<p><a href=\"http://blogpal.seesaa.net/article/22560511.html\">FIFTH EDITION: メディア・ゲーム・ネットで進む非同期化</a></p>\n\t\t\t<blockquote>\n\t\t\t<p>すいません。ちょっと分かりにくいところが有るので質問します。</p>......

長いので途中で省略。「いそいで口で吸え」というエントリでcreated_onとmodified_onがnullなせいでしょうか。投稿日付が9999-01-01になってるのがそもそもの原因なの?よくわからない。Perlわかんねー…勉強せねば。

つーか「いそいで口で吸え」というと、「かんたまがきゆいのです」とか「やんこまりたい」とか「めんたまにきんそれーたむを塗ると、きつにじもちがいい」とか「ポール・マッカートニー取調室の菊池です」とか思い出しました。どうでもいいですね。

,

最近契約したinetdというレンタルサーバに、Plaggerをインストール。Plaggerはなにかっつーと、要するにmixiとかBloglinesとかLivedoor Readerとかそういうところからデータを持ってきて、何かしら変換して吐き出すためのPerlスクリプト。俺の場合は普段Livedoor Readerを使ってRSSを読んでるので、そっから未読のフィードだけを取ってきてGmailで読めるようにした。ついでにmixiのマイミク新着記事やメッセージも、全部Gmailで読めるように。すばらしい。

Plaggerは依存モジュールがかなり多いので、インストールは結構大変。でもまぁPerl素人な俺でも出来たので、基本的には誰でも出来そうな気がする。手順としては

$ perl -MCPAN -e shell

で、色々質問されるけど全部デフォルトでOK。で

>cpan test Plagger

して依存モジュールがバラバラ出てくるので片っ端からinstallしていくだけ。基本的にはhttp://capsctrl.que.jp/kdmsnr/diary/20060803.html#p02に書いてあるようにすりゃいけるはずなんだけど、そう甘くなかった。とりあえず、

$ perl -MCPAN -e ‘CPAN::Shell->install(CPAN::Shell->r)’

で最新にして、あとはエラーが出てるモジュールをシコシコ手動でインストールしたらいけた。

足りないモジュールをメモっておく→1つずつCPAN searchで調べる→tar.gzなファイルをwgetで持ってくる→perl Makefile.PL→gmake→gmake test→gmake install の繰り返し。時間かかったけどとりあえず動くようになった…のでcronでmixiは1時間ごと、フィードは10分ごとに回してる。快適すぎる!つかEntryFullTextプラグインがすごい。del.icio.usのnetwork RSSなんかもオリジナルのサイトへ行って全文取ってきてくれるので非常に便利。やばい。

というわけで、俺のmixiのログイン時間は常に1時間以内になっていると思われ、かつマイミクのみんなのとこには足跡が付きまくっていると思われ…まぁ気にしない方向でお願いします。

ぼくはまちちゃん!で有名なはまちや2さんのエントリ、XSS - 表示系パラメータに存在する盲点を見て。

そもそもWebアプリケーションにおいて、表示系だとかユーザからの入力で云々だとか、そんなこととは関係なくシステムが扱う外部からの入力では、かつ出力に影響する部分ではすべからくスクリプトの無効化を行うべきでしょう。パラメータ然り、HTTPヘッダ然り。改行コードを削除して、>・<・’・”・&・スペースは全部エスケープ。コーディングする人は「それが実際にエスケープする必要があるのかどうか」は考えなくていいようにするべきだ。

たとえばどう考えても数値しか取らない変数hogeと、何が入ってくるのかわからない変数mogeがあったとして、それを出力するときにmogeだけをエスケープするのは間違っている。hogeもmogeも同じように処理するのが正しい。なぜならhogeが数値しか取らないことを確認するためには、ソースコードの他の部分を参照して確認する必要があるからだ。そんなのは時間の無駄。そこだけを見て問題ないことが確認できるようにしておくべき。もちろんエスケープすると想定の動作をしないこともあるわけだが、そんなことは例外。どうしてもタグを出力したいとかいうときだけ、例外的に特定のタグだけ許すようにするべき。

なんでそういうことをちゃんと書いてあるセキュリティ関係の本ってないのかな。あるけど俺が知らないだけ?

, ,

今運用している某システム、MyISAMのある難癖によって非常に辛い目に遭っております。それはもちろんテーブルロック。これはもうMyISAMを選択した時点でどうしても避けては通れない道。そこんところ仕組みをちゃんと理解してないと、MyISAMのほうが速いって言うから選んだのに、なんだよ全然遅いじゃん!っていうか使い物にならないよウワァァァァンみたいなことになりがち。今のシステムでどうやってMyISAMかInnoDBかを分けたのかというと、単純に更新頻度だった。頻繁に更新されるテーブルはInnoDB、そうじゃなければMyISAM。参照が殆どならInnoDBを選択するメリットは何もないと思っていた。が、実は全然そうじゃなかった。

MyISAMが辛いのは、INSERT文実行時にテーブルロックされることもそうだが、時間のかかるSELECT文を実行したときにREADロックされることなんじゃなかろうか。特に業務系のシステムを構築する場合、何かと複雑なSQLを発行せざるを得ない場合がある。それはもちろんテーブル設計を行った者の技量不足や、プログラマの技量不足が原因であることが多いのだが、不可避な理由(例えばクソくだらない出来損ないのコーディング規約など)によってそうせざるを得ない場合も、悲しいかな下っ端風情の一プログラマには良くあることだ。そこを正していくのが本筋だけども、そこはオトナの事情というかまぁ色々あるので以下略(もちろん技量不足が理由の大半なんだろうけども)。

この場合レプリケーションしていたとしても、悲惨な結末を辿る。例えばマスタ1台に対してスレーブを3台用意していたとしよう。普通に考えるとスレーブへの接続はラウンドロビンで順番に割り振ってやるわけだが、あるSQLによって1台のスレーブが長時間テーブルロックするとシステム全体に影響が及んでしまう。アクセス数が多ければ多いほど(というか発行するSELECT文が多ければ多いほど)、ある時間のかかるSQLによってどっかがテーブルロック→ロックしてないスレーブではすぐに結果を返す→単純なラウンドロビンなのでロックしてるスレーブにすぐに順番が回ってくる→ひたすら実行待ちSQLがキューに入る→コネクション使い切る。かと言ってロックを監視して、それによってどのスレーブに接続するかを選択するってのはオーバーヘッドが大きすぎる気が。ロックによる待ち時間よりは全然ましかも知れないけど…

と言うわけで、InnoDBにするかMyISAMにするかは、単純に更新頻度で考えてはいけないことになる。例え参照が大半を占めようとも、ある程度複雑で時間のかかるSQLを投げることが避けられないのならInnoDBにするべきだ。で、InnoDBとMyISAMと共存してるけど、特にInnoDBだからどうこうということはないように思うです。バックアップに関してはレプリケーションしてれば特に問題ないと思うし、気になるとすれば速度とディスク容量でしょうか。結構InnoDBは容量食うので注意が必要。速度に関してはSQLによるとしか言いようがないので、実際に試してみる以外ないかと。naoyaさんが言っているような「運用が面倒臭いのは萎える」のは例えばどのようなことを言ってるのかわかりかねますが…俺の中のイメージでは定期的にoptimizeしてあげたりしなくちゃいけない分、MyISAMのほうが運用は面倒なのではと思ったりします。

ちなみにMyISAM の「速い」というのがどう速いのか、という疑問についてはインデックスが絡んでいるのでは?MyISAMは文字列のキーに対してプリフィックス圧縮を行うのに対してInnoDBでは単なるB-Tree。また、InnoDBではINSERTやUPDATEのたびにインデックスの統計情報が最適化されるが、MyISAMではoptimize tableしない限り最適化しない。あとMyISAMはMVCCじゃないので、COUNTがインデックス見ただけで分かるので速い。それ以上はソース読んでないのでわかりませぬ…ちゃんと読んでみようと思いながら怠けてます。

結局のところ俺の中では、単純なSELECT文しか発行しない、かつDELETEやUPDATEが極端に少ないテーブルならMyISAM、それ以外はInnoDB、という結論で落ち着いています。あくまで4.1系の話ですが…5系はInnoDBが極端に遅いという話も聞く(検証はしてない)のでよくわからず。でも5.1からNDB Clusterがオンメンモリじゃなくても動くようになるらしいので、それについては動向をウォッチして行きたい所存。

, , ,