[cakePHP] Paginator->sortのデフォルトのソート方向を変更

cakePHPのPaginatorってスゴく便利でよく使ってるのですが、Paginator->sortで作るlinkのデフォルトのソート順を変更したかったのでソース追っかけてみた。
ソート順のデフォルトがascなのですが、ネタ的にdescでソートされてほしかったのです。

cakePHP 1.3.2ね
で目的のメソッドは cake/libs/view/helpers/paginator.php にありましたので
単純にデフォルトのdirectionがascなのをdescにしただけでおしまい


function sort($title, $key = null, $options = array()) {
$options = array_merge(array('url' => array(), 'model' => null), $options);
$url = $options['url'];
unset($options['url']);

if (empty($key)) {
$key = $title;
$title = __(Inflector::humanize(preg_replace('/_id$/', '', $title)), true);
}
//$dir = isset($options['direction']) ? $options['direction'] : 'asc';
//↑を↓にしただけ
$dir = isset($options['direction']) ? $options['direction'] : 'desc';
unset($options['direction']);

$sortKey = $this->sortKey($options['model']);
$defaultModel = $this->defaultModel();
$isSorted = (
$sortKey === $key ||
$sortKey === $defaultModel . '.' . $key ||
$key === $defaultModel . '.' . $sortKey
);

if ($isSorted) {
$dir = $this->sortDir($options['model']) === 'asc' ? 'desc' : 'asc';
$class = $dir === 'asc' ? 'desc' : 'asc';
if (!empty($options['class'])) {
$options['class'] .= ' ' . $class;
} else {
$options['class'] = $class;
}
}
if (is_array($title) && array_key_exists($dir, $title)) {
$title = $title[$dir];
}

$url = array_merge(array('sort' => $key, 'direction' => $dir), $url, array('order' => null));
return $this->link($title, $url, $options);
}

CakePHP 1.3によるWebアプリケーション開発―オープンソース徹底活用
掌田 津耶乃
秀和システム
売り上げランキング: 11952
Filed under: cakePHP,Programming — maesan 11:42 PM

[cakePHP] XML-RPCしてみた

ちょっとサーバー間で処理をさせたいことがあったのでXML-RPCしてみることにしました。
単純にGETとかPOSTとかでやってもよかったのですが、前からXML-RPCに興味があったのでちょっと勉強がてらやってみました。

前準備

で、簡単に調べたのですがズバリそのもの「How to create an XML-RPC server with CakePHP」ってのがあって、あまりにも簡単に出来すぎて勉強になりませんでしたw

とりあえずこのページからxmlrpc.zipてのをダウンロードしてapp/vendor/xmlrpc.phpにコピー

Controller

ま、これも上のページにサンプルがあるのでまんまコピーでおk
XML-RPCサーバークラスのインスタンスを作るときにコンストラクタにコールバックを渡せばおkなので例えばフィボナッチ数を返す処理をつくろうと思ったらこんな感じで


<?php

// Import the app/vendor/xmlrpc.php library
App::import('Vendor', 'xmlrpc');

class XmlRpcController extends AppController {

// This demo doesn't need models
var $uses = array();

// The XML-RPC server object
var $server = null;

function index() {

// Disable debug information
// Required to generate valid XML output
Configure::write('debug', 0);

// Avoids render() call
$this->autoRender = false;

// XML-RPC callbacks settings
// Use this parameter to map XML-RPC methods to your protected or private controller methods
$callbacks = array();
$callbacks['Fibonacci'] = array(&$this, '_fibonacci');

// Handle XML-RPC request
$this->server = new IXR_Server($callbacks);
}

// Protected Method
function _fibonacci($n) {
if ($n <= 2) {
return 1;
} else {
return $this->_fibonacci($n - 1) + $this->_fibonacci($n - 2);
}
}
}

?>

Client

次はそれを呼び出すクライアントを作ります。
クライアントはcakePHP関係なしな感じです。
コレもサンプルコピペでおkですが、まぁこんな感じで

client.php


<?php
require_once(dirname(__FILE__) . '/xmlrpc.php');

$url = 'http://localhost/xml_rpc';

$client = new IXR_Client($url);

if (!$client->query('Fibonacci', 30)) {
die('Something went wrong - '.$client->getErrorCode().' : '.$client->getErrorMessage());
}
echo $client->getResponse();
echo "\n";

?>

実行してみる

>php client.php
832040

まとめ

てな感じであまりにも簡単すぎるので全くXML-RPCの勉強にはなりませんでしたw
このままだとあんまり意味が無いので今度は別の言語でクライアント実装してみるかなと。。。
そういや昔SOAPとか流行ったからちょっと仕事で使ったけどXML-RPCってそれと同じようなもんだっけ?

Programming Web Services With Xml-Rpc
Simon St. Laurent Joe Johnston Edd Dumbill
Oreilly & Associates Inc
売り上げランキング: 159906
Filed under: cakePHP,Programming — maesan 1:47 AM

マニラの空港の手荷物検査で大変なことになった

シンガポールから帰国するときにマニラ経由のチケットだったのですが、マニラでの手荷物検査で大変なことになったのでまとめてみる。

手荷物検査で何か引っかかったらしい
検査官A:ちょっとカバンチェックね
私:おk
 (カバンに特に問題無し)

検査官B:財布もおk?
私:どぞ
B:特に何も無いなぁ
A:でも何か引っかかったぞ
私:コレ?
 (財布の奥の方に薬莢が入っていたのを思い出した)

B:おっとコレはやっちゃったね
私:え!?
 (まさかアウトとは思っていなかった)

A:英語わかる?
私:まぁちょっとは
A:アレ見て
 (なんか看板指差す)

A:こういうのね、罰金10万香港ドルなんだよね
 (金額はうろ覚えだけど、こんなもんだった)

私:え!?
 (てか何で香港ドル!?)

私:別にこれ弾じゃないし空じゃん、危なくないじゃん
A:扱いは一緒なんだよねぇ
私:え!?
A:君なにしてる人?
私:あ、IT関係のエンジニアですが?
A:ふ〜ん、でコレどこで?
私:去年くらいにタイで
A:フィリピンじゃないのね
私:はい
A:まぁ、別にウチらは警察じゃないけど、とりまオフィスにきてもらわないと
私:いやいや、納得いかないし、弾じゃないし
A:(こっそり懐から銃を出して弾倉を見せながら)
A:コレといっしょの扱いです
私:マジで!?
 (てかそんな危ないものを出さないでください><)

A:いっしょです。記録を残さないとダメなのです
私:いやいや、今までそんなことは無かったけど?
A:フィリピンは厳しいのですよ、これからどこ行くの?
私:日本に帰りますが
A:そうですか
私:ちょ、シンガポールからのトランジットだが、何もなかったよ?
A:見つかんなくてよかったねぇwシンガポールは多分もっと厳しい
私:(いや、ちょっと待って、言ってる意味分かんないですw)
A:まぁ、記録が残って今度フィリピンくるとき入れないかもしれないね
 (別にフィリピン来たくてきてるわけじゃないんだが?)
A:何なら助けてやろうか?
 (間違いなく賄賂目的じゃねーかコレ)
A:秘密にしてやってもイイんだよ
 (ったく初めてこういう世界に遭遇したぜ)
A:まぁ記録残って罰金払うんならイイけど?
私:んでどうすりゃ助けてくれるんだ?
A:う〜んどうしよっかな?
私:いやいや、俺どうなんの?どうすればイイんだ?
A:そうだな〜
 (絶対に自分から金よこせとは言わないw)

私:で、金?
A:(ニヤリ)
私:でもいくら欲しいわけ?
A:そのままだと100,000香港ドルだよねぇ
私:そんなに金ないよ?てか香港ドルのレートわかんないからいくらか分からん
A:おk、レート説明するからあっちのベンチで座って話そうか
 (いやいや、検査場スルーじゃんwもう何が何だか、とりあえず財布のお金を見つからないように別の財布に入れてカバンに隠す)
 (こういう時に限って1万円札しかないし。。。)
 (とりあえず1万円札と500ペソだけ財布に残してあとは隠した)
 (2人の検査官に挟まれるように座られレートの説明始まる)

A:10,000円は5000ペソで〜、100,000香港ドルは〜
 (手にペンで書いて説明してくる)

私:(万が一ホントに薬莢がアウトだったらいやなので、説明終わる前にとにかく諦めて1万円を渡す)
A:(そそくさと懐に隠してレートの説明継続w)
私:いや、もうお金ないんだよ、これ以上は払えない
A:おk、まぁ聞いて、10,000円は5000ペソでな、香港ドルは〜
私:いや、無いから。これ以上はお金ないし払えない。
 (とにかくガシっと力強く抱きつくようにして威圧+お願いしてみる)

B:コレは?あぁ、ペソか
 (財布を開けてペソを見つける)

私:(ペソには興味ないのかよw)
A:まぁこれはここでコーヒーとかご飯食べないといけないしねw
 (ちょwなにその親切w)
A:おkおk、もうこれ以上は払わなくてイイよ、何か名刺とかある?
私:(ちょ、おま、コレをネタに今後もゆするつもりか?w)
私:いや、今は持ってないわ(持ってても出すかよw)
A:おkおk、名前覚えとくし、今度フィリピン来たら一緒にあそびにいこうぜw
 (ちょwおまw何友達になってんだよw)
A:射撃とか案内するぜw好きなんだろ?w
 (いや、ちょw話おかしいw)
A:ま、今後はこういうもの持ち込まないって約束な
 (小指出してくるwフィリピンでもゆびきりげんまんあるのか?w)
私:おk、親切にありがとう(正直納得いかないw)
A:おk、気をつけてな〜コレは「ないしょ」だから誰にも言うなよ〜
 (ホントに日本語で「ないしょ」って言って人差し指を口にやったw)
私:(やっぱおめーもバレたらやばいんだろーが?w)
私:おk、「ないしょ」な、親切にどうもありがとうw

もう何ていうかフィリピン怖いです。
正直二度と来たくありません><

いまやっとネットにつながるようになって調べたら薬莢でもアウトなことがあるらしいね。。。
今回は結果オーライなのか。。。?
1万円の罰金に減額になったと思って諦めます><

とりあえずみんな、海外で射撃とかしても薬莢持って帰ってくるなよ、絶対だぞ!

スカイ・クロラ 押井守モデル 薬莢(やっきょう)型ドアチャイム
プロモーショナル・パートナーズ・ワールドワイド (2008-08-25)
売り上げランキング: 48654
Filed under: 未分類 — maesan 1:40 PM

ロリポブログからWordPressにURLを変更せずに移行する

ロリポップの契約更新期限が来たのですが、メールはGoogle Apps使ってるし、基本的にテストサイト等はheteml使ってるし、ロリポップってこのblogくらいしか使わなくなっちゃったんですよね。
んで、そのままblogの為だけにまた1年更新するのも管理が面倒でもったいない気がするのでhetemlに一本化しようかと思ってロリポブログ→WordPressの移行をやってみた。
んでやっぱりURLが変更されるのもちょっと切ないので無理矢理URLを変更せずに移行(厳密には前のURLから辿れるように)した。

エクスポート

ロリポブログの「設定」→「エクスポート」でxml形式にて保存する。
で、そのままだとjugem形式なので一旦WordPressでインポート可能なMT形式を迂回する。
このサイト素晴らしい!JUGEM形式のブログデータをMovableType4形式に変換

画像はこのエクスポートではもちろん付いてこないので、ロリポブログの画像管理からチマチマと画像をダウンロードしとく。。。
とりあえずoption+クリック連打で保存した><
あと、WordPressだとカテゴリとかでURLが階層構造になるので、画像のパスが “images/xxx.png” とかになってるのを絶対パスの “/images/xxx.png” にしておく。
エクスポートしたファイルをエディタで置換!

インポート

WordPressの管理ページの「ツール」→「インポート」で「Movable Type and TypePad」をクリックしてさっきのファイルをアップロードする。
これだけだと画像がないので、記事の画像パスに合うようにルートフォルダにimagesってフォルダを作り、さっきダウンロードした画像達をftpとかでアップロードする。
WordPress的な画像の管理方法ではないのですが、イチイチ手作業でアップしてられないので気にしないことにする!

URLを保持する

とりあえずの移行だったらこれまでの手順でいけるのですが、数は少ないと思いますがリンク張ってくれたりブクマしてくれてる方もおられますので、前のURLから辿れるようにする。
ロリポブログの場合URLが http://ブログ/?eid=xxxxx って感じなのですが、そもそもこの記事のIDが引き継がれません><
かなり地味な作業になるのですが、記事のIDを手作業で振りなおす必要があります。

↓私はこんな手順でやりました
・ロリポブログの記事管理から記事の一覧をコピペして、Excelに貼っつける
・WordPressの記事IDを追記
・CSVで保存して適当なスクリプトでこんなSQL文を生成


update wp_posts set ID = xxxxxx where ID = yyy ;
update wp_comments set comment_post_ID = xxxxxx where comment_post_ID = yyy ;
update wp_term_relationships set object_id = xxxxxx where object_id = yyy ;
:
:

※wp_postsのGUIDにもURLが書いてあるのですが、どこで使うのかわからないので放置。。

ちなみにスクリプトはPythonで書いたこんなの(A列に本来の記事ID、H列にインポート後の記事IDとする)
改行コードはCRLFってコトで(MacのExcelの場合CRになるから注意)


for line in open("blog.csv"):
dat = line[:-2].split(',')
print "update wp_posts set ID =",dat[0]," where ID = ",dat[7],";"
print "update wp_comments set comment_post_ID = ",dat[0]," where comment_post_ID =",dat[7],";"
print "update wp_term_relationships set object_id = ",dat[0]," where object_id = ",dat[7],";"

これで記事IDが一致するのですが、WordPressのURLは http://ブログ/?p=xxxxx なので若干違う。
mod_rewriteとかで対応しようとしたのですが、どうもGETパラメータを含むURLをうまくrewriteできないので(mod_rewriteとか正規表現苦手です><)、かなり無理矢理感がありますがindex.phpを書き換えたw


if (!empty($_GET['eid'])) {
$id = $_GET['eid'];
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://blog.maesan.jp/'.$id.'.html');
}

※これをindex.phpの先頭に追加で。
※パーマリンクの設定を %post_id%.html にしているのでこうしてますが、各自の設定でやってください。

まとめ

思ったよりは簡単に出来ましたが、それでも面倒です。。
やっぱり気をつけることは画像関係でしょうか、本来のWordPressの方法ではないので次に別のところとかに移行するときにまた大変になるような気はします。んでGUIDってフィールドも若干気にはなるw
なんというか、ブログ専用のサービスとか使うと始めるにはすごく楽なんですけど、いざというときに自由がきかなくて大変ですねぇ。

Filed under: Internet — maesan 7:08 PM

EC2から送信したメールがspam扱いされてたのを回避するまでの記録

EC2でサイトの運営を開始したのですが、そのIPがブラック(ブロック)リストに載っててメールが届かない人がいたので、それを回避するまでのメモを残します。
ウワサには聞いていたのですが、あまりに気していなかったのはテストとかで自分とか携帯とかに普通に送れてたのでリストに載ってなかったり、こういうスパムリストってあんまり使ってないのかなと軽く考えていたからでした。
で、何で発覚したかというとフツウにメールのログに見慣れない文字列が出てきたからです

Sep 1 15:03:43 xxxxxxxx postfix/smtp[7722]: 5DA663A64F: to=, relay=mail.xxxxxx.jp[xxx.xxx.xxx.xxx]:25, delay=4.4, delays=0.05/0/4.1/0.17, dsn=4.0.0, status=deferred (host mail.xxxxxx.jp[xxx.xxx.xxx.xxx] said: 451 http://www.spamhaus.org/query/bl?ip=xxx.xxx.xxx.xxx (in reply to RCPT TO command))

spamhausだと!?
ま、とりあえずサービス開始直後にコレなわけでw
ちょっと洒落にならず急いで以下の対処方法を考えてみた
・IPをリリースして再取得してリストから離れるのを待つ
 →EC2のシンガポールのIPすべてリストに載ってるらしいから却下w
  しかもDNSの浸透の関係で即効果がでないため現実的ではない。。。
・何にせよ削除申請
 →spamhausのAWSのレンジは削除申請できない?
  どうやら自動で削除されるらしいから何にせよすぐには反映されない
  いずれにせよDNSの逆引きとかの対処が必要
・他のサーバーへのRelay
 →幸いこのドメインはGoogle Appsでメールを運用しているのでとりまgmailを使ってメール送ることにする

DNSの逆引き設定

どうやらspamhausは動的IPアドレスということでリストに載せているらしい。確かにEC2でインスタンス立ち上げてメール大量送信してインスタンス落とせば簡単にspamを送信できるし、足もつきづらいよね。
だからと言ってEC2のレンジ全部入れるなよとw
で、DNSの逆引きレコードが登録されていたら動的IPじゃないと認めてくれるっぽいのでDNS逆引きレコードを登録する必要があるわけです。
正直この判定って気休めでしかないし共用サーバーとかでは不可能だわなw
そのへんがブロックリストに載ったらどうするんだろうね?w
とりあえず以下のページからAWSに申請する
https://aws-portal.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request
これ申請する直前にメール送信数制限解除の申請してたから(もちろんまだ制限解除されていない状態)連続でやるのは気まずい気がしたが、仕方なく送信。
簡単に説明を英語で書かないといけないけど、まぁ適当な英語でおk
んでこれ反映されるまで時間かかるのでその間にSPFの登録をする

SPFの設定(value-domainの場合)

メール送信者がドメインを偽装してないよって証明するのがSPF証明ってやつなのですが、仕組みを簡単に説明するとドメインに対してこのIPアドレスとかホストとかからメールを送信しますよってのをDNSに登録することです。
ようするに
・DNSの設定である → ドメインの所有者である
・DNSにこのIPからしかメール送りませんよと宣言
・登録されていないIPからメールが送信された → ドメインの所有者ではない
→偽装メールだよ
って仕組みです。
細かい仕様とか設定方法とかは他の賢い人に任せるとして、以下の前提の場合設定はこんな感じ
・IPアドレスがxxx.xxx.xxx.xxx
・google appsでメール使ってる

txtレコードとして以下を登録
v=spf1 ip4:xxx.xxx.xxx.xxx include:_spf.google.com ~all

試しにメールを送ってヘッダ情報を確認するとReceived-Spfってのがあると思います。

Gmailを使ってメール送信

DNSの逆引きやらSPFを登録したところで、今まさに送信できない状況をすぐに解決はできないので緊急手段としてGmailを使ってメールを送信することにした。
サーバーはDebian、メールはPostfixでとりあえず動いてる状態とする
・gmailのsmtpは認証が必要なのでSASL入れる
#apt-get install sasl2-bin
#apt-get install libsasl2-modules

・/etc/postfix/main.cf にrelayhostの設定する


relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl/passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_tls_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
smtp_use_tls = yes
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt

・認証用のパスワードファイル作る
#echo [smtp.gmail.com]:587 xxxxxxxx@xxxxxx.com:password > /etc/postfix/sasl/passwd
#postmap /etc/postfix/sasl/passwd

パスワードが平文で入ってるので気持ち悪いから見えないように
#chown root:root /etc/postfix/sasl/passwd
#chmod 600 /etc/postfix/sasl/passwd

・Postfixを再起動する
#/etc/init.d/postfix restart
これでgmailで送信できるようになったよと
もしエラーとか拒否のときだけgmail使うようにしたかったら、


relayhost =
fallback_relay = [smtp.google.com]:587

で行けると思われます

まとめ

結局当日には逆引きもリスト解除も間に合わなかったのでgmailでメール送信する形になっちゃいました。
翌日には逆引きも反映され、spamhausのリストからも外れていました。(ホントに自動だぜw)
ついでにmapsにも登録されていたっぽいので、逆引きも反映されたので削除申請しておきました。
なんつーか気持ちは分からないでもないけど、こういうスパムリスト的なものはあまり使ってほしくないなと思いましたw
大手だとhotmailはそうだし、独自ドメインとか自前サーバーとか使ってる人の中でもspamhausを使ってる人がいて困りましたね。
もし複数ドメイン運用しているサーバーとかだったら、全部のドメインでGoogle Apps使ったり送信者登録するのも現実的ではないしまた別の方法を考えないといけないかもですねぇ。
まぁちょっと不謹慎ですが、今回は色々勉強できて面白かったですw

ホーメル スパム 20%レスソルト 340g
ホーメル 売り上げランキング: 1136
Filed under: AWS — maesan 1:42 PM

Debianにnslookupが入ってなかった

EC2でDebianのAMIを使ってたんだけど、ふとnslookupを使いたくなってコマンドいれたら入ってなかった。。。

#apt-get install dnsutils

で入った。
いつも当たり前に入ってると思ってたのが入ってなかったのでちょっと焦った。

よくわかるAmazonEC2/S3入門 ―AmazonWebServicesクラウド活用と実践 (Software Design plusシリーズ)
藤崎 正範 深海 寛信 五十嵐 学 馬場 俊彰 技術評論社 売り上げランキング: 46496
Filed under: AWS — maesan 6:28 PM
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)