ゆるめ

ゆるめなのは公開範囲です。

はてなブログに移りました

はてな事を書くつもりでいたらはてなポイントが数か月前に尽きていたのを思い出して、まあ良い機会だしということではてなブログに移行しました。*1

今までだったらポイントが尽きた頃に人力検索に出稼ぎに行ってたのですが、ポイントシステム自体がもう無くなるらしいので、じゃあもうなすがままなくなるがままでいこうと思いました。人力検索に行かないとなると、質問にトラックバックでアクロバティック回答することもなくなるだろうと思い、心置きなくトラックバックを飛ばせないはてなブログに移行しました。

移行した後で メロディ再生記法非対応だと知ってがっかりしたので、その辺はなんとかしたいと思います。しました。ついでに修正時刻の挿入も半自動にしました。

と書いてるそばから q 要素の cite 属性展開もされなくなってることに気づいたので、それもまたなんとかします。しました。そしたら今度は修正時刻保存機能が機能してなくて、泣く泣く手動で時刻を入れました。

はてな事を主に書きますが、公開範囲が「はてなにログインしてる人」という、自分にしてはかなりゆるめに保たれてる状態を活用して !はてな事を書くかもしれません。書かないかもしれません。

関連記事

*1:移転前のはてなダイアリーはポイントを払わないとブログが書けないシステムでした。

question:1335280813

解けたものの諸事情で忍ばせた回答です。

http://h.hatena.ne.jp/keyword/%E6%A0%97%E3%81%BE%E3%82%93%E3%81%BE%E3%80%80%E5%8F%A3%E3%81%AB%E3%81%97%E3%81%9F%E3%81%BE%E3%81%BE%E3%80%80%E5%8F%A3%E8%AA%AC%E3%81%8F%E3%81%95%E3%81%BE
ひらがなかカタカナか分からなかったので、用心してどっちも取りました。

UNIX time で言うと 1335287046 頃に忍ばせたみたいです。

今年のはてなエイプリルフールは影が薄め

2012年 4月 2日 12:00 時点で question:1333231682 の質問文にあるサイトおよび回答に載っていなかったので、挙げておきます。
B!KUMA フールズ - ネットで話題のウソっぽい記事を素早くチェック!

フォトライフの画像は割と丸見え

question:1332381053 での回答コメントに関する補足です。


補足の前に前置きから。
フォトライフの認証周りはとってもカジュアルなつくりになっているため、公開範囲を狭めに設定したフォトライフ画像でも、画像 URL (http://〜.png など) を直接開けば誰でも閲覧可能な状態になっています。
加えて、画像表示ページ (http://f.hatena.ne.jp/pacochi/20120324195100 など) から画像 URL を推測することも容易に可能です。
たとえば、http://f.hatena.ne.jp/pacochi/20120324195100 なら、http://f.hatena.ne.jp/images/fotolife/p/pacochi/20120324/20120324195100.png になります。
細かく分けて説明するとこんな感じです。

http://f.hatena.ne.jp/ images/fotolife/ p/ pacochi/ 20120324/ 20120324195100 .png   
現在フォトライフで表示される画像のドメインは cdn-ak.f.st-hatena.com ですが、f.hatena.ne.jp でも同じ画像が表示されます。   はてな ID の一文字目 はてな ID 画像 ID の先頭から八文字分 画像 ID .jpg, .png, gif のどれかです。勘で探ります。.jpg の場合、本体 (.flv) が存在する可能性もあります。


また、上記のような URL をぽちぽち打たなくても、自分のダイアリーの記事を書くページを開いて、以下のように加工した文字を貼り付けて、「確認する」ボタンを押してプレビューすれば、さっくり閲覧できます。

[f:id:pacochi:20120324195100p:image]
[f:id:pacochi:20120324195100j:image]
[f:id:pacochi:20120324195100g:image]
[f:id:pacochi:20120324195100f:movie]

四行のうちどれかが展開されて、画像もしくは動画が表示されるはずです。ちなみに [f:id:pacochi:20120324195100f:movie] が展開される場合、 [f:id:pacochi:20120324195100f:image] で画像ファイルが出てきます。 (今回の例では出てきません。)
ダイアリーを開設していなくても、フォトライフ記法が展開されるところならどこでも可能です。
そんな感じなので、フォトライフに正真正銘ひみつ画像を置くと後で恥ずかしいことになるかもしれません。


その辺の恥ずかしさはさておき、ここからが本題です。私が数日前に書いた以下のコメントについてです。

フォトライフのトップから辿れないよう非公開フォルダに回答画像を置いていて、3月26日 10:50 の少し前くらいに別フォルダに移そうと考えているので、実は忘れてちゃいけないんですけどね。

http://q.hatena.ne.jp/1332381053#ac21249

前置きの通り、非公開フォルダに入れてもフォトライフ記法や個別ページを伝えた時点で見ようと思えば見ることができる状態になるので、実のとこフォルダ移動なんて忘れてても平気だったりします。
しかし、これも前置きの通り、そのままだと閲覧の手間が微妙にかかるので (そしてその辺の仕組みを知らない人はお手上げ状態になってしまうので)、皆様の手を煩わせるつもりはないよ、という意味で「忘れてちゃいけない」と発言しました。
が、これだと「非公開フォルダに画像を置いておけば、表示ページの URL やフォトライフ記法が知られても見られちゃうことはないんだ、安心だね」という誤解を与えかねないことに気付いたので、このエントリを書きました。
若干繰り返しになりますが、フォトライフは色々と油断ならないので、公開範囲を設定したからといって安心せず慎重に使って下さい。


せっかくこの辺に触れたので、似たような事例のこともおまけで書いておきます。
はてなダイアリーで「Twitter上でのツイートまとめを定期的にブログに投稿」する設定にしているアカウントのツイートは、ID や URL が分かれば、 twitter 上で鍵付きだろうとダイアリーがプライベートモードだろうとお構いなしに見ることができます。
フォトライフの時と同じように、twitter 記法が有効なところでプレビューするだけです。

[twitter:171084712608145408:detail]

私のはてなダイアリーtwitter のアカウントもプライベートモードですが、上記のような指定であっさり発言が出てきます。

フォロワーさんからのリプライなどで ID が分かっちゃうこともあると思うので、ダイアリーと連携している鍵付きアカウントは、ちょっと控えめな公開アカウントみたいなものだと思っておいた方が良いかもしれません。


あともうちょいおまけで書きますが、hatena code petit はその辺を活用したショートカットをしても最終解答に辿り着けないようになっています。
フォトライフ + なぞなぞ認証を使った問題を出す際は、この問題のようになぞなぞ認証のフレーズを再利用するか、画像表示ページのタイトル欄も併せて見ないと分からないような画像にした方が堅実だと思います。

HideMyAnswer で隠された回答を見るユーザスクリプト 1.2

1.1 からのバージョンアップです。コメント欄に書かれた回答も見るようにしました。
Firefox 用アドオンができるまで個人的に使うつもりのつなぎをご近所さんにおすそ分けしてるような気持ちなので、どっかに登録したりずっと更新し続けたりはしないと思います。

// ==UserScript==
// @id          ShowOurAnswer
// @name        ShowOurAnswer
// @version     1.2
// @namespace   id:pacochi
// @author      pacochi
// @description HideMyAnswer を見るだけ
// @include     http://q.hatena.ne.jp/*
// @run-at      document-end
// ==/UserScript==

(function() {

if (!document.URL.match(/q\.hatena\.ne\.jp\/\d+(#|$)/)) return;

var url = 'http://hidemyans.appspot.com/getAnswer';
var hma = {};
var pick = function(ansXpath, timeXpath) {

	var ans = document.evaluate(ansXpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

	for(var i = 0; i < ans.snapshotLength; i++) {

		var ap = ans.snapshotItem(i);

		if(ap.nodeType == 3 && ap.nodeValue.match(/HideMyAnswer:(\d{13})/)) {

			var id = RegExp.$1;
			var timestamp = document.evaluate(timeXpath, ap, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
			var atime = Date.parse(timestamp.singleNodeValue.nodeValue);

			// 早く回答した方だけ変換
			if (typeof(hma[id]) == 'undefined' || hma[id].atime > atime) hma[id] = { atime: atime, ap: ap };

		}

	}

};
var req = function(id) {

	GM_xmlhttpRequest({
		method: 'POST',
		headers: { 'Content-type': 'application/x-www-form-urlencoded' },
		url: url,
		data: 'hidemyansid=' + id,
		onload: function(res) {

			var txt = document.createElement('span');
			txt.style.cssText = 'display:block; padding:1em; border:1px solid #F6AC5A;';
			var lines = res.responseText.split('\n');

			for (var i = 0; i < lines.length; i++) {

				if (i > 0) txt.appendChild(document.createElement('br'));
				txt.appendChild(document.createTextNode(lines[i]));

			}

			hma[id].ap.parentNode.insertBefore(txt, hma[id].ap);

		}
	});

};

// 回答欄
pick("id('read_answer_list')//div[@class='answer-detail clearfix']/div[@class='section clearfix']/p/text()",
 "ancestor::div[@class='answer' or @class='answer reply_content']/h3/span[@class='timestamp']/a/text()");
// 回答コメント欄
pick("id('read_answer_list')//div[@class='answer-comment-detail']/div[@class='section']/p/text()",
 "ancestor::div[@class='section']/span[@class='timestamp']/text()");
// 質問コメント欄
pick("id('comment-section')//div[@class='comment-content clearfix']/text()",
 "ancestor::li/div/span[@class='comment-time']/a/text()");

for(var id in hma) req(id);

})();

HideMyAnswer で隠された回答を見るユーザスクリプト 1.1

Hide My Answer (question:1331264191question:1331284462 などで使われているサービス) の回答を、今メインで使っているブラウザでさっくり見たかったのですが、Firefox 用のアドオンなどはまだ開発されていないみたいなので、自分でちまちまユーザスクリプトを書きました。

// ==UserScript==
// @id          ShowOurAnswer
// @name        ShowOurAnswer
// @version     1.1
// @namespace   id:pacochi
// @author      pacochi
// @description HideMyAnswer を見るだけ
// @include     http://q.hatena.ne.jp/*
// @run-at      document-end
// ==/UserScript==

(function() {

if (!document.URL.match(/q\.hatena\.ne\.jp\/\d+(#|$)/)) return;

var url = 'http://hidemyans.appspot.com/getAnswer';
var req = function(id) {

	GM_xmlhttpRequest({
		method: 'POST',
		headers: { 'Content-type': 'application/x-www-form-urlencoded' },
		url: url,
		data: 'hidemyansid=' + id,
		onload: function(res) {

			var txt = document.createElement('span');
			txt.style.cssText = 'display:block; padding:1em; border:1px solid #F6AC5A;';
			/* みんな適度に改行するタイプならこれでもいいと思う
			txt.style.cssText = 'display:block; padding:1em; border:1px solid #F6AC5A; white-space:pre;';
			txt.appendChild(document.createTextNode(res.responseText));
			*/
			var lines = res.responseText.split('\n');

			for (var i = 0; i < lines.length; i++) {

				if (i > 0) txt.appendChild(document.createElement('br'));
				txt.appendChild(document.createTextNode(lines[i]));

			}

			hma[id].ap.parentNode.insertBefore(txt, hma[id].ap);

		}
	});

};
var ans = document.evaluate("//div[@class='section clearfix' and starts-with(@id, 'answer-formatted-body-')]/p/text()",
 document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var hma = {};

for (var i = 0; i < ans.snapshotLength; i++) {

	var ap = ans.snapshotItem(i);

	// Node.TEXT_NODE って書いたら undefined になった
	if(ap.nodeType == 3 && ap.nodeValue.match(/HideMyAnswer:(\d{13})/)) {

		var id = RegExp.$1;
		// 数日前まで書かれてた「reply_content」が質問によっては消えてたのを確認 (20120316)
		//var name = document.evaluate("ancestor::div[@class='answer reply_content']/h3/span[@class='timestamp']/a/@name",
		var name = document.evaluate("ancestor::div[@class='answer' or @class='answer reply_content']/h3/span[@class='timestamp']/a/@name",
		 ap, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
		var aid = parseInt(name.nodeValue.substr(1), 10);

		// 早く回答した方だけ変換
		if (typeof(hma[id]) == 'undefined' || hma[id].aid > aid) hma[id] = { aid: aid, ap: ap };

	}

}

for (var id in hma) req(id);

})();

Scriptish でしか確認してないので、他のやつだと動かないかもしれません。

以下追記です。

回答周辺のクラス名が変更されていたので修正しました。
回答欄の他に、回答コメント欄と質問コメント欄も変換する版 (ver 1.2)を書きました。