まさに雑記。2007年10月04日 03時24分36秒

時間がとれん。

会社の引越しなどもあって、ブログ書く時間がなかなかとれない。その割にはたんぶらにぬこ登録してるが。たんぶらのほうもほとんどぬこ専用状態。最近ろくにダッシュボードみてないし。

今度の週末にはなんとかZF入門の続き書かなきゃ。

Inkscapeが楽しい。

なんとなくInkscapeが楽しい。前触ったときはもっと使い物にならない感が満載だったが、いまは割とストレスなく使える。

いや、あるか。グリッド幅を任意に調整できなかったり、グラデーション編集するときにカラーパレットやスウォッチからドラッグドロップできなかったり、ウィンドウ切り替えのタイミングでまれに無限ループにハマったり。。。

でも、こんだけの機能のものが無償で手に入るってのはうれしいことだ。選択したオブジェクトだけビットマップエクスポートできるのは便利。

ドローソフトは楽しいなぁ。もちっとゆっくり触りたい。

液晶モニタは目が痛い。

会社のモニタを新調した。これまで後生大事にナナオの19インチCRTを使っていたが、やっと許可が下りたので20インチの液晶を調達した。

とりたてて高機能なやつではないが、一昔ふた昔前のものに比べると発色もコントラストも良好で、なによりバックライトが明るくなっている。

そのせいか、CRTに比べると画面の白色部分がやけに目に刺さる。が、モニタの輝度を落とすと今度は青みが強く、寒々しい感じになるし。調整が難しいなぁ。色温度、5000と6500の間が欲しい感じ。

部屋残すの!?2007年10月07日 19時28分01秒

大相撲の名門・時津風部屋の継承者が6日、西前頭7枚目の時津海正博(33)=長崎県出身=に事実上決まった。

うわちゃー、なんだか無理やりって感じだな。ここまでして部屋残すんだ。誰のために

これだけの騒動(というか事件だな)を巻き起こしておいて、問題の親方を処分しただけの、「トカゲの尻尾きり」でお茶を濁しておしまい、ってのは納得いかんでしょ。

錦島親方は「本人はまだ(現役を)やりたいようだが…。師匠が空白になっているという初めてのケースなので、いろいろと(手続きが)難しいことがある。9日までにははっきりさせる」と、話すにとどめた。
そりゃ現役続けたかろうよ、まだ33だし。が、今回の事件は部屋全体で起こしたものだから、時津海自身が「かわいがり」に参加していようがいまいが、無関係ではないのだから、現役続けるにしろ部屋を継ぐにしろこのままのうのうと角界に残れるってのは、なんだかなぁ...

北の湖理事長は5日の会見で「名門なので、なくすのは忍びない」と語り、部屋の不祥事にも継承を容認。
「忍びない」って... 結局、これだけの騒動になっても協会側が反省する気がないってワケかよ。

なんにしても、亡くなられた斎藤さんのご冥福をお祈りいたします。

「Webページ取得JSONP」でアサブロランキングを取得する2007年10月08日 01時50分12秒

アサブロのランキングを取得してみたり

Mashupediaで、JSONPで指定URLのソースを取得できるWebサービス「Webページ取得JSONP」が紹介されていたので、なんとなくアサブロのランキングを取得するライブラリを作ってみた。例によって、要prototype.jsで、ライセンスはNYSL。

ソース

こんな感じ。

var AsabloRanking = {
	callback : function(source) {
		var result = {};
		var dateMatch = /<div class="left">([\d\/]+)/g.exec( source );
		if( dateMatch ) result.date = dateMatch[1];
		
		var reg = /<div class="no(\d+)">.*?(<div class="ranking-([^"]+)"><\/div>\s*)?<a class="blogtitle" href="([^"]+)">([^<]+)<\/a>/;
		result.ranking = source.match( new RegExp( reg.source, "g" ) ).map( function(data) {
			var match = reg.exec( data );
			return match ? 
			{
				rank : Number( match[1] ),
				title : match[5],
				url : match[4],
				updown : match[3] || "top3"
			} : null;
		} );
		
		this.result = result;
		this.requesting = false;
	},
	request : function(callback) {
		this.requesting = true;
		this.result = null;
		
		var node = document.createElement("script");
		node.src =[
			"http://www.yoshimeux.com/wiss/HttpResponse.ashx",
			"?url=",
			encodeURIComponent("http://dir.asablo.jp/blog/ranking/"),
			"&callback=AsabloRanking.callback&charset=utf-8"
		].join("");
		
		var _self = this;
		
		document.getElementsByTagName("head")[0].appendChild( node );
		
		setTimeout( function() {
			if( _self.requesting ) {
				setTimeout( arguments.callee, 10 );
				return;
			}
			
			callback( _self.result );
		}, 0 );
	}
}

ダウンロードはこちら

使い方

結構シンプルで、AsabloRanking.requestメソッドにコールバックを指定するだけ。コールバックには

{
	date : "2007/10/07",
	ranking : [
		{
			rank : 1,
			title : "いちばんのブログ",
			url : "http://~",
			updown : "top3"
		},
		:
		:
	]
}
みたいなオブジェクトが渡される。

ルートにある「date」は現在確認可能なランキング対象日付の文字列。 rankingはArrayで、各要素は、

  • rank - 順位(1~100)
  • title - ブログタイトル
  • url - ブログURL
  • updown - 順位の変動状況(前日比)
の形式のオブジェクトが1~100位まで格納されてくる。

updownは以下のように定義。

  • top3 - トップ3
  • nochange - 変動なし
  • up1、up2 - 上昇。up1が変動量が大きい
  • down1、down2 - 下落。down1が変動量が大きい
定義ったって、ランキングページのクラス名から拝借してるだけなんだけども。

サンプル

button#get_ranking_071008とdiv#ranking_071008を設置したとして、こんな感じで使ってみる。

$("get_ranking_071008").onclick = function() {
	// updownプロパティの値の変換テーブル
	var updowns = {
		top3 : "☆",
		up1 : "<b>↑</b>",
		up2 : "↑",
		down1 : "<b>↓</b>",
		down2 : "↓",
		nochange : "→"
	};
	
	var target = $("ranking_071008");
	target.innerHTML = "ランキング取得中...";
	
	AsabloRanking.request( function(result) {
		target.innerHTML = "<h3>" + result.date + "</h3>";
		
		result.ranking.each( function(rank) {
			var item = document.createElement("div");
			item.innerHTML = [
				"<div>",
				"<b>" + rank.rank + "</b>",
				" " + updowns[ rank.updown ] + " ",
				"<a href=\"" + rank.url + "\">" + rank.title + "</a>",
				"</div>"
			].join("");
			target.appendChild( item );
		} );
	} );
}

で、こんな感じになる。

このサンプルではそのまま1~100位までを出力しているが、特定のブログの順位を取得してサイドバーに表示したりとかもできたりできなかったり。

なんてものを作ってはみたが

ほとんど需要なかろうて...

HttpWebRequestとオレオレ証明書2007年10月10日 02時42分05秒

まずは1発目。

いま抱えてる仕事が月末納期で、そろそろ詰めの段階にきているのだが、本番系のサーバに暫定でオレオレ証明書を入れてSSL通信を始めた。

基本はWebアプリなのだが、印刷周りだけはWebじゃ如何ともしがたいため、C#で印刷アプリも作っていて、認証と基本情報の取得にWebアプリとHttpWebRequestで通信を行っているのだが、これがいきなりハマった。「リモート サーバーとの信頼関係を確立できませんでした」というやつだ。

証明書のインストールが必要かと思い、IEでアクセスして証明書のインストールを行ったが状況が改善しない。IEで表示される警告をよくよく読んでみると、どうやら(証明書の発行元が確認できないのはもちろんだが)証明書そのものが通信しているサーバ向けではなく、他のサイト向けとして発行されているとのことだ。

で、もう少し調べてみたら、MicrosoftのKBで「PRB:「 System.Net.WebException」 基になる接続は、閉じられました。 「リモート サーバーとの信頼関係は確立できる」でした。 .NET Framework をアップグレードすると、エラー メッセージ」なんてのが見つかった。

機械翻訳なので少々アレだが、

他のシナリオは、存在します。 たとえば、外部クライアント versus 内部的に一部のネットワークが別の名前解決方式を使用します。証明書が(www.adatum.com)などパブリック URL とイントラネット アプリケーションでサーバーに発行される場合に、内部ドメインネーム システム DNS サーバーは、(www.internal.corporate.adatum.com)など同じサーバーの別の名前を指定します。 この SSL での Web サービスの要求は、失敗することがあります。 この変更は、 SSL を使用する Web サービスのセキュリティを強化するのが行われます。
なんてことが書いてあり、どうやらそのものズバリくさい。

なので、このページに掲載されていたサンプルにあるように、「サーバが送りつけてきた証明書を無条件に信頼するICertificatePolicyを実装し、ServicePointManagerに設定する」という、なんともアレな回避策で無事(?)回避することができた。

ま、リリース時はちゃんとした証明書を発行してもらう(つか、手続き中)ので問題ないんだけども、なんだかなぁ、というお話でした。

fgetcsvでハマってみたり2007年10月10日 02時43分46秒

ハマりネタ2発目。今度はPHP。

普段は自分の開発PC(WinXP)上のApache+PHPで開発を行っているのだが、試験用のデータを登録するため、本番系のサーバで動作させてみた。

今回動作させたのが、CSVファイルのアップロードなのだが、かなり不可思議な現象に見舞われた。

アップしたCSVのデータのうち、マルチバイトの文字が欠落するのだ。それも全部が全部ではなく、二重引用符や丸括弧で囲っているデータは大丈夫で、それ以外の文字が落ちるという現象だ。

たとえば、

注文ID(消さないでください),注文日,...
なんてデータをfgetcsv()で読み込んで行ごとにprint_r()してみると、
Array(
    [0] => ID(消さないでください),
    [1] =>
     :
     :
)
のように、最初のフィールドでは「注文ID(消さないでください)」の「注文」部分のみが欠落、次のフィールドではすべての文字(すべてマルチバイト文字)が欠落、といった感じで、どうもシングルバイト文字が出現するまで無視されているような感じになるのだ。

fgetcsv()で読み込む前に、アップロードしたファイルを一括して文字コードを変更し、それを読み込む処理をしているのだが、文字コード変換後のファイルをfile_get_contents()でダンプしてみると、特に文字化けもしていない。

print_r()の結果を見たところ、フィールドの区切りも誤認識しているわけではないし、さらに、自分の開発PC上ではまったく同じコード・同じデータで問題が発生していない。もうどうなってるやらさっぱり

と、泣きそうな気持ちで必死に調べたところ、「[PHP-dev 1206] Re: PHP5のfgetcsv()関数について」と、大いに関係ありそうな記事が見つかった。

この記事によると、

PHP 5.0 の fgetcsv() はロケールの設定に依存します。
とのこと。さらにこのスレッドの先を見てみると、
少々乱暴ですが、 setlocale(LC_ALL, 'ja_JP.UTF-8'); で、UTF-8のCSVファイルについてはfgetcsv()は希望通りに動作しました。
とあったので、試してみたら、これビンゴ。多分PHP.INIの設定の違いだったのかなぁ。

一瞬自前でCSVデコードせにゃならんかと思って結構鬱になったりならなかったりだったが、なんにしても解決策(というか回避策?)が見つかってほっとした。ちとバッドノウハウくさい気もするが。PHP.INIを見直しておくかなぁ。