Firefox のアドオン PicLens.これはすごい.ぐっと来た.
あまりにぐっと来たので,衝動的にこのサイトでも対応してみた.対応のしかたは以下のページに書いてある.
要は,画像の場所を列挙した Media RSS という XML ファイルを作って, RSS Autodiscovery で見つけさせればよい.うちの Media RSS はこんな感じになった.
Firefox で PicLens をインストール済みの方は,メニューバーの右側
(Firefox の場合)
(追記・訂正)
Storable の互換性の問題 [2006-
ここにある「$
というわけでここの真似をして,いったん perl 5.
*
dump.
#! / usr/ local/ bin/ perl5. 6. 2 use strict; use lib " . " ; # 古い Storable 一式をカレントディレクトリに置いた use Storable; use Data: : Dumper; $ Data: : Dumper: : Indent = 0; $ Data: : Dumper: : Useqq = 1; while (<* . stor. old>) { my $ new_ file = $ _ ; $ new_ file = ~ s/ stor$ / txt/ ; open(NF, " > $ new_ file" ) or die; my $ data = Storable: : retrieve($ _ ) ; print NF Data: : Dumper- >Dump([$ data] , [" data" ] ) , " \ n" ; close(NF) ; }
restore.
#! / usr/ local/ bin/ perl5. 8. 8 use strict; use Storable; while (<* . txt>) { my $ new_ file = $ _ ; $ new_ file = ~ s/ txt$ / stor/ ; open(OF, $ _ ) or die; my ($ line, $ data) ; $ line = <OF>; eval $ line; close(OF) ; Storable: : store($ data, $ new_ file) ; }
いろいろとありまして,しばらく放置しておりましたが,なにやら巷では 「3ヵ月空白があると連続したブログとは見なされない」という定義があるらしく,まあどうでもいいっちゃどうでもいいのですが,継続は力なりとか唱えながら再開してみます.
この辺の対策 [2007-
アクセス元ホストはわりとバラバラな感じ.ただし 6/
*
というわけで [2007-
今回のケースに置き換えると,サーバは計算問題を生成して (これがトークン)
ということでそれを実装すればよいのだけど,どうもぐっと来ない.なぜぐっと来ないのか考えた結果,思い当たったのは以下の 2 点:
ぐっと来ないものを作ってもろくなことにならないのでとっとと却下する.
というわけで考え方を変えてみる.要は,投稿のリクエストに関して,
という条件を満たせばよいのかな.これでどうだろう.
実装はとりあえず以下のような感じ.$
<div class=" arith" > <br> コメントスパム回避のため,以下の足し算の答えを半角でご記入下さい: <br> $ arith_ x + $ arith_ y = <input class= " field" name= " arith" value= " " > <input type= " hidden" name= " arith_ token" value= " $ arith_ token" > <input type= " hidden" name= " arith_ hash" value= " $ arith_ hash" > </ div>
を仕込み,これを表示する直前に
my $arith_ x = int(rand(9) ) + 1; my $ arith_ y = int(rand(9) ) + 1; my $ accepted_ tokens = {} ; if (- e $ arith_ token_ file) { $ accepted_ tokens = Storable: : lock_ retrieve($ arith_ token_ file) ; } my $ arith_ token; do { $ arith_ token = Digest: : MD5: : md5_ hex($ logid . $ q- >remote_ host() . int(rand(2 * * 32) ) ) ; } while (defined($ accepted_ tokens- >{$ arith_ token} ) ) ; my $ arith_ hash = Digest: : MD5: : md5_ hex($ arith_ token . $ arith_ passph . ($ arith_ x + $ arith_ y) ) ;
とする.ここでは token ファイルは読み込んでいるだけなのに注意.
if ($
my $arith = $ q- >param(' arith' ) + 0; my $ arith_ token = $ q- >param(' arith_ token' ) ; my $ arith_ hash = $ q- >param(' arith_ hash' ) ; my $ accepted_ tokens = {} ; if (- e $ arith_ token_ file) { $ accepted_ tokens = Storable: : lock_ retrieve($ arith_ token_ file) ; } if (defined($ accepted_ tokens- >{$ arith_ token} ) ) { exit; } elsif ($ arith_ hash ne Digest: : MD5: : md5_ hex($ arith_ token . $ arith_ passph . $ arith) ) { exit; } else { $ accepted_ tokens- >{$ arith_ token} = 1; Storable: : lock_ store($ accepted_ tokens, $ arith_ token_ file) ; }
とした.
トークンの生成は適当で構わないのだけど,発行済みのトークンで過去に受理されたもの,および受理される可能性のあるものと重複しないようにだけは気をつける必要があるので,何かむにゃむにゃな処理をやっている.
うーむ,ちっともお手軽じゃなくなってきた.いろいろ工夫してみたところで所詮足し算を実行されたら終わりですからね.なんかベクトルが間違っている気がしないでもない.
現状の問題点:
というか何か根本的に見過ごしていることがあるような気がしてならない….どんなもんでしょ.
(追記)
2007年05月06日 kazuhooku しょうもないつっこみしてすみません。よっぱらいつつの感想:
syncookies のようなゼロ記憶だと難しいのかな。 http:
/ / b. hatena. ne. jp/ entry/ http: / / www. kagami. org/ diary/ 2007- 05- 05- 1. html
恥ずかしながら syncookies って初耳だったのでちょっと勉強.
なるほど.トークンを乱数を使って作る代わりに時刻を使うことにして,一定時間経過してたら reject するってことになりますかね.ハッシュ値の計算に時刻をつっこんでおくことで,サーバ側の保存無しで expire をチェックできるところがミソだと理解しました.
「一定時間」をうまく設定してあげる必要があるかも.短いとコメントを書いているうちに expire しちゃうし,長いとその間は固定パラメータ攻撃されちゃいますよね.まあ 1 時間くらいにしておけば実用上十分な気がしますが.
…というのが SYN cookies の動作を単純にマッピングした場合の話だと思いますけど,もしかするともっとうまい応用のしかたがあったり…?
というわけで [2007-
気になるのは,そもそもスパムでないコメントすら一切届いていないことなのだが,まあ普段からコメントを頂くことは稀なのでよしとしよう.
というわけで実装の話.くっつきBBSの $
<div class=" arith" > <br> コメントスパム回避のため,以下の足し算の答えを半角でご記入下さい: <br> $ arith_ x + $ arith_ y = <input class= " field" name= " arith" value= " " > <input type= " hidden" name= " arith_ x" value= " $ arith_ x" > <input type= " hidden" name= " arith_ y" value= " $ arith_ y" > </ div>
みたいなのを仕込み,これを表示する直前に
my $arith_ x = int(rand(9) ) + 1; my $ arith_ y = int(rand(9) ) + 1;
とする.んで,if ($
my $arith = $ q- >param(' arith' ) ; my $ arith_ x = $ q- >param(' arith_ x' ) ; my $ arith_ y = $ q- >param(' arith_ y' ) ; if (! $ arith | | $ arith ! = $ arith_ x + $ arith_ y) { exit; }
を加える.実際には単に exit するのではなくて,ログを取るようにしてあるけど省略.
(追記)
2007年05月02日 kazuhooku ?
arith_ x= 1&arith_ y= 1&arith= 2 みたいな固定化への対策が望ましいんじゃないかと思った。実質的には「何か」の入力を求めている時点でスパムよけとしては十分だろうけれども http:
/ / b. hatena. ne. jp/ entry/ http: / / www. kagami. org/ diary/ 2007- 04- 30- 1. html
まったくおっしゃる通りで,パラメータの意味を理解すれば固定パラメータによる攻撃は可能です.パラメータとして渡すべき「問い」は「そこに書いてある」ので,原理的にはまあ同じことかと思ってたけど,実際の攻撃手順を考えてみるとそこにはちょっと敷居の差があるかなあと改めて思った.
というわけでちょっくら修正してみようかと思ったのですが,考え始めるといろいろややこしいので,別記事 [2007-
*
コメント欄 (くっつきBBS)
というわけで,アクセシビリティは落ちてしまうけど,簡易 CAPTCHAもどき
(?
で,果たして真面目に破ろうとしてくるスパマーがいるのかどうかに興味がある.しばらく様子を見よう.
*
chalow の「Referrer (Inside)
でもこの [YYYY-
とここまで書いて,w3m.
この [YYYY-
(defvar chalow-date- regexp " ^ [01- 9] + - [01- 9] [01- 9] - [01- 9] [01- 9] " ) (defvar chalow- itembullet- regexp " ^ \ t\ \ * " ) (defun chalow- date- to- datestr (str) str) (defun chalow- kill- datestr () (interactive) (save- excursion (let ((curpos (point) ) ) (if (re- search- backward chalow- date- regexp nil t) (let ((itemnum 1) (dstr (buffer- substring (match- beginning 0) (match- end 0) ) ) ) (goto- char curpos) (if (not (re- search- forward chalow- date- regexp nil t) ) (goto- char (point- max) ) ) (while (re- search- backward chalow- itembullet- regexp (1+ curpos) t) (setq itemnum (1+ itemnum) ) ) (kill- new (format " [% s- % d] " (chalow- date- to- datestr dstr) itemnum) ) (message (car kill- ring) ) ) (message " date not found" ) ) ) ) )
Ctrl-
先頭の方の変数とかをいじれば,ChangeLog とは違うフォーマットで書いている場合にもある程度適用できるんではないかと思います.(というか私がそうしてます)
最近,copyurl+
コピーしたページによっては,タイトルの先頭にカテゴリ名がついている場合とか (tDiary なんかが典型)
*
[を] chalow でアスキーアートを表示するためのプラグイン [tech] [aa] :
-http: / / nais. to/ ~ yto/ clog/ 2006- 09- 23- 3. html
これを chalow の ChangeLogReader.
というわけで修正してみる.ややこしいな.合ってますかこれ?
-if ($ ih = ~ s/ \ s* \ [(. + ) \ ] $ / / ) { # category + if ($ ih = ~ s/ \ s* \ [(([^ \ [\ ] ] + \ ] \ s* \ [) * [^ \ [\ ] ] + ) \ ] $ / / ) { # category @ cat = split(/ \ s* \ ] \ s* \ [\ s* / , $ 1) ; }
ここしばらく,外部に公開する記事しか chalow を通していなくて,外部に公開する記事の場合タイトルとかは自分で整理し直すので気づいていなかった.ふと久しぶりに全記事を chalow に通したら「File name too long」なエラーが出て気づいた.
(追記)
*
*
*
*
*
*
ついで [2006-
というわけで以下を bookmark してください.
javascript:(function() { / * setClipboard for Firefox LastModified : 2006- 01- 10 http: / / la. ma. la/ misc/ js/ setclipboard. txt * / function setClipboard(text) { var url = [ ' data: text/ html;charset= utf- 8;base64, PGJvZHk+ PC9ib2' , ' R5PjxzY3JpcHQgdHlwZT0idGV4dC9qYXZhc2NyaXB0Ij4KKGZ1' , ' bmN0aW9uKGVuY29kZWQpe3ZhciBzd2ZfZGF0YSA9IFsKICdkYX' , ' RhOmFwcGxpY2F0aW9uL3gtc2hvY2t3YXZlLWZsYXNoO2Jhc2U2' , ' NCxRMWRUQjJ3JywKICdBQUFCNG5EUGdZbGpBd01qSTRNejAlMk' , ' YlMkY5JTJGZTJaZkJnYUdhV3dNRE1uNUthJywKICdrTU10TjRH' , ' ZGdaZ1NJTXdaWEZKYW01UUFFJTJCQm9iaTFCTG5uTXlDcFB6RW' , ' 9oU0dJJywKICdQRnAlMkZBeHNEREJRa3BGWkRGUUZGQ2d1eVM4' , ' QXlqSTRBRVVCaXkwVndBJTNEJTNEJwpdLmpvaW4oIiIpOwpkb2' , ' N1bWVudC5ib2R5LmlubmVySFRNTCA9IFsKICc8ZW1iZWQgc3Jj' , ' PSInLHN3Zl9kYXRhLCciICcsCiAnRmxhc2hWYXJzPSJjb2RlPS' , ' csZW5jb2RlZCwnIj4nLAogJzwvZW1iZWQ+ JwpdLmpvaW4oIiIp' , ' Owp9KSgi' , btoa(encodeURIComponent(text) + ' " ) </ ' + ' script>' ) ] . join(" " ) ; var tmp = document. createElement(" div" ) ; tmp. innerHTML = ' <iframe src= " ' + url+ ' " width= " 0" height= " 0" ></ iframe>' ; with(tmp. style) { position = " absolute" ; left = " - 10px" ; top = " - 10px" ; visibility = " hidden" ; } ; var b; try { / * modified by swk * / b = top. frames[0] . document. body; } catch (e) { b = document. body; } b. appendChild(tmp) ; setTimeout(function() {b. removeChild(tmp) } , 1000) ; } function extractText(node) { var text = ' ' ; if (node. nodeType = = 3) { / * TEXT_ NODE * / text = node. nodeValue; } else if (node. hasChildNodes() ) { var n = node. childNodes. length; for (var i = 0; i < n; i+ + ) { text = text + extractText(node. childNodes[i] ) ; } } return text; } function fmt(title, href) { return ' \ r\ n\ t* ' + title + ' : \ r\ n\ t- ' + href + ' \ r\ n' ; } var clog = ' ' ; var h3s = top. basefrm. document. getElementsByTagName(" h3" ) ; for (var i = 0; i < h3s. length; i+ + ) { var a = h3s[i] . getElementsByTagName(" a" ) [0] ; clog = clog + fmt(extractText(a) , a. href) ; } setClipboard(clog) ; } ) () ;
しかしこう bloglines や Firefox に仕様変更がある度に振り回されるのは何とかならんものか.何か根本的に方針を間違っている気がしないでもないなあ.
いろいろ文句言いながらも,しつこく bloglines 使ってます.
以前書いた keep new を解除する bookmarklet [2006-
今までの bloglines では keep new のチェックボックスをクリックするとそのたびにページ遷移が発生していたのだけど,最近 Ajax 対応したらしくページ遷移しなくなった.というわけで bookmarklet の方で自前で Ajax 化する必要はなくなって,本家が用意してくれている JavaScript 関数を呼びまくるだけでよい.ずいぶんシンプルになった.
javascript:(function() { var ipts = top. basefrm. document. getElementsByTagName(" input" ) ; for (var i = 0, k = 0; i < ipts. length; i+ + ) { if (ipts[i] . type = = " checkbox" && String(ipts[i] . onclick) . match(/ markUnreadItem\ (\ s* (\ d+ ) \ s* , \ s* (\ d+ ) \ s* , \ s* (\ d+ ) \ s* , . * \ ) / ) && ipts[i] . checked = = true) { var siteid = RegExp. $ 1; var subid = RegExp. $ 2; var itemid = RegExp. $ 3; ipts[i] . checked = false; top. treeframe. keepItem(siteid, subid, itemid, false) ; } } } ) () ;
*
ソースコードなどを blog などに貼りつけるときにどうするのがよいか,という話がちょっと前に話題になっていたりして,その論点の一つに「横に長すぎる場合」をどう扱うかが挙がっていたりするのだけど,実は似たような問題はほかにもある.連続するASCII 文字列である.
典型的には,長ーい URL 文字列を表示した場合に,枠からはみ出したり,枠自体がびろーんと伸びて見ずらくなったりする.といっても Firefox の場合だけなのだけど.
対策法がこちらによくまとまっている:
ざっくり要約すると,まず Firefox ユーザ側の立場としては,
一方,Firefox を使っているかどうかに関らず,ウェブサイトの運営側の立場としては,
ちょっとややこしいのは,url_
A要素のみ処理 | 全文を処理 | |
xpi | url_ | 同左 (オプション設定) |
Greasemonkey | url_ | url_ |
というわけで,実はしばらく前からウェブページ側に仕込んでみている.
url_
<script src=" / js/ url_ breaker_ plus. user. js" type= " text/ javascript" > </ script>
と入れる.
url_
// var regexp = new RegExp(" ([! - % ' - / : = \ \ ? @ \ \ [- ` \ \ {- ~ ] | & ) " ) ; var regexp = new RegExp(" ([! - % ' \ \ ) - / : = \ \ ? @ \ \ \ \ - ` \ \ | - ~ ] | & ) " ) ;
さて,実は長い文字列が横に伸びちゃうのが一番うっとうしいと個人的に思っているのは bloglines なのけど,url_
blog に限らずウェブサイト全般の話やけども,実名を晒して運営するのか,それともあくまで匿名で運営するかは,
自由だ─────!
という犬井ヒロシ風の前フリは置いといて,実名サイトと匿名サイトの間のインタフェースには,たまにややこしい場合があるという話.
ここは実名サイトなのでそっち側の立場からの見方だけど,匿名サイトの中には,たとえば個人的人間関係とかによって「実は誰がやっているか」を知っているサイトがあります.そういう場合,そのサイトの記事にリンクを張ったりトラックバックしたりとかするときに,その文脈によっては人間関係に関する情報を含んでしまうことがあり得て,結果として相手の素性をバラしてしまうことになるのではないかと躊躇することがあります.
というかその辺に無頓着だったせいでバラしてしまったことが過去におそらく多数あります.すんません.今もやってるかもしれません.
逆に言うと,そういう (つまり個人的知合いの)
あと,そもそも実名を隠したいのかどうなのかよくわからなくて悩むこともありますが,まあそれはそれということで.
(以下やや私信)
というわけで「site:
ついでに書くと,「でもこの人,トップページには名前書いてるよなー」とか疑問に思いました.
(私信おわり)
「画像で取得するAPI」ではてなブックマーク件数をお手軽に表示してみた矢先なのだが [2006-
はてなが重いときとか反応しないときに,自分のページの表示が影響を受けるのが嫌だってのがまずあるけど,そのときに,あー,俺いまはてなサーバに無駄に負担かけてるーという罪悪感があって精神衛生上よろしくない.
(いや,もちろんトラフィック全体からみると,うちから発生する分なんて誤差に過ぎないわけですが,単に気持ちの問題なので)
つうわけで真面目にはてなブックマーク件数取得APIを叩いてみることにしたですよ.
やり方はいろいろあると思いますが,定期的に件数を取りに行っておいて,
HTML から SSI で include することにしてみた.こんなのを cron で定期的に走らせます:
#! / usr/ bin/ perl use strict; use XMLRPC: : Lite; my $ html_ clog_ url = ' http: / / www. kagami. org/ diary' ; # don' t add trailing slash my $ html_ clog_ dir = ' / home/ swk/ www/ diary' ; my $ hatebu_ count_ dir = ' / home/ swk/ www/ hatebu_ count' ; my $ EndPoint = ' http: / / b. hatena. ne. jp/ xmlrpc' ; my @ urls = () ; while (<$ html_ clog_ dir/ * . html>) { next unless / \ / (\ d{4} - \ d{2} - \ d{2} - \ d+ ) \ . html$ / ; my $ ymdi = $ 1; push(@ urls, " $ html_ clog_ url/ $ ymdi. html" ) ; if (@ urls = = 50) { &writecount(\ @ urls) ; @ urls = () ; sleep(3) ; } } if (@ urls > 0) { &writecount(\ @ urls) ; @ urls = () ; } sub writecount { my ($ uref) = @ _ ; my $ map = XMLRPC: : Lite- >proxy($ EndPoint) - >call(' bookmark. getCount' , @ {$ uref} ) - >result; foreach (@ {$ uref} ) { my $ url = $ _ ; my $ count = $ map- >{$ _ } ; my ($ ymdi) = ($ url = ~ / \ / (\ d{4} - \ d{2} - \ d{2} - \ d+ ) \ . html$ / ) ; if ($ count > 0) { my $ str_ count = $ count . " user" . (($ count > 1) ? ' s' : ' ' ) ; my $ str = << " HTML" ; <span class= " hatebu_ count" > <a href= " http: / / b. hatena. ne. jp/ entry/ $ html_ clog_ url/ $ ymdi. html" > $ str_ count</ a></ span> HTML ; &save_ file(" $ hatebu_ count_ dir/ $ ymdi. htmlin" , \ $ str) ; } elsif (- e " $ hatebu_ count_ dir/ $ ymdi.
*
[Cryptogeox]
Bitcoin tradicionalmente relacionam-se a... (2018-08-17 12:29:42)
*
[KulDole]
Lump armpit brings discomfort, hurts whe... (2018-08-13 19:23:19)
*
[MirkaFele]
Peels can help to eliminate from the gre... (2018-07-26 03:16:04)
*
[KIRANags]
To determine internal swelling is diffic... (2018-07-09 10:37:45)
*
[FimaInabs]
Useful information for every pregnant. D... (2017-11-03 19:01:15)
*
...