2010年9月29日水曜日

Mewで送信するメールのMessage-IDを変える

中小零細企業でインターネットにかかわる仕事をしていると、まったく面識もない人からメールが来る(よくわからない問合せだったり、クレームだったり、営業だったり)。

会社の仕事なのでスルーできないが、なるべくこちらの情報を提出したくない、という場合にメールヘッダを無意味なものに書き換える必要が生じる(自意識過剰気味)。

※SMTPサーバーが処理するエンベロープまでは手が出せないので、MUAでできる範囲。

  • Fromは編集時にバッファで書き換えればいい
  • Mewによって自動生成される「Message-ID」は、以下のように2つの変数の値を変更すればいい(マニュアルを読めば書いてある)
    (setq mew-smtp-msgid-user "no-reply")
    (setq mew-smtp-msgid-domain "no-reply.co.jp")
    

こうすると、

Message-Id: 01234567.012345.012345678.no-reply@no-reply.co.jp

という形式のMessage-IDが生成される。

2010年9月28日火曜日

JavascriptでUNIXタイムスタンプを得る

こちら↓の記事そのまんま。

Get a UNIX timestamp with Javascript

var ts = Math.round(new Date().getTime() / 1000);

new演算子とドット「.」の評価順序を陽に示したい場合は次のように書けばいい。

var ts = Math.round((new Date()).getTime() / 1000);

用途はいろいろあるだろうけど、今回はFlash(SWFファイル)をブラウザにキャッシュさせないために使用。クエリストリングにタイムスタンプを付加して、SWFファイルのURLを毎回変化させる。次のような感じで。

   // このコードは swfobject.js(http://code.google.com/p/swfobject/)に依存しています

   var serial = Math.round(new Date().getTime() / 1000); // タイムスタンプをシリアル番号として利用
   var flashvars = { };
   var params = { allowScriptAccess: 'sameDomain', allowFullScreen: 'false', scale: 'noscale', quality: 'autohigh', wmode: 'transparent', base: '/swf', menu: 'false', salign: 't' };
   var attributes = { id:'movie01', name:'movie01' };
   swfobject.embedSWF("/swf/movie.swf?s=" + serial, "myContent", "600", "300", "9.0.0",  "/swf/expressInstall.swf", flashvars, params, attributes );

もっとトリッキーな方法

Math.roundやMath.floorを使わずに、浮動小数点数から整数への暗黙の型変換(英語もついでに覚えよう:implicit type conversion)で切り捨てを実現することもできる。

補数演算(ビット反転)による切り捨て
var ts = ~~(new Date()/1000);    //~ が補数演算子。2回作用させれば元の値に戻る
論理和演算(OR演算)による切り捨て
var ts = new Date()/1000|0;    //| がOR演算子。ゼロとのORゆえ実質的には型変換のみ行われる

2010年9月20日月曜日

Perlのプロファイラ Devel::DProf

シンプルなプロファイラ。標準モジュールなので、すぐに使える。

$ perl -d:DProf ./p.pl  ;; あるいはシェバング行に追加してもよい(#!/usr/local/bin/perl -d:DProf)
$ dprofpp
Total Elapsed Time =   0.0096 Seconds
  User+System Time =        0 Seconds
Exclusive Times
%Time ExclSec CumulS #Calls sec/call Csec/c  Name
 0.00       - -0.000      1        -      -  strict::import
 0.00       - -0.000      1        -      -  strict::bits
 0.00       - -0.000      1        -      -  warnings::BEGIN
 0.00       - -0.000      1        -      -  warnings::import
 0.00       - -0.000      2        -      -  main::BEGIN
 0.00       - -0.000     11        -      -  main::__ANON__
 0.00       - -0.000      7        -      -  main::pow3
 0.00       - -0.000     12        -      -  main::pow2
 0.00       - -0.000     64        -      -  main::pow

参考

Devel::DProf

2010年9月1日水曜日

CakePHP paginateのカスタマイズ

URLをカスタマイズ

とりあえず、"Paginator"が生成するURLを文字列置換する方式。これを共通部品にするため、app/views/elements/ の中に"element"を作成する。

app/views/elements/pagination.ctp

<?php
$prev_link = str_replace('page:', '',
                         $paginator->prev('前のページ', null, null, array('class' => 'disabled')) );
$prev_link = preg_replace('/\/1"/', '"', $prev_link);

$numbers_link = str_replace('page:', '', $paginator->numbers());
$numbers_link = preg_replace('/\/1"/', '"', $numbers_link);

$next_link = str_replace('page:', '',
                         $paginator->next('次のページ', null, null, array('class' => 'disabled')));

echo $prev_link;
echo $numbers_link;
echo $next_link;
?>

このelementを呼び出すためのコード(Viewに記述)。

  <?php echo $this->element('pagination'); ?>

Routesの変更

paginateのURLに対応するため、Routing情報を追加。

app/config/routes.php

/* pagination */
  Router::connect('/:controller/:action/:page',
                  array('action' => 'index', 'page' => null),
                  array('action' => 'index', 'page' => '[0-9]+'));

ここでconnect()の引数は、

  • URLは controller名/action名/page名 の形式になっている
  • controller名に対応するControllerが呼び出される(デフォルトのRouting)
  • action名に対応するActionではなく、強制的にindexを呼び出す(デフォルトのRoutingを変更)
  • page名はnull可(オプショナルな「カスタムRoute要素」)
  • action名は"index"という文字列にマッチしないといけない
  • page名は半角数字列にマッチしないといけない

というような意味。