2007/09/29

はてな
注意:os0xさんからの指摘で、ちゃんと動かないらしいです。

javascript:var d=document,t,i,l,m=[];l=d.getElementsByTagName('span');for(i=0;i<l.length;i++){if(l[i].className=='hatena-star-star-container')m.push(l[i]);}t=d.createElement('input');t.type='text';t.onblur=function(){var v=d.createElement('div');v.innerHTML=t.value;m[0].appendChild(v);m[0].removeChild(t);};m[0].appendChild(t);void(0);
  • ↑のコードをアドレスバーにゴニョゴニョゴニョ
  • 出てきたテキストボックスにゴニョゴニョゴニョ
  • フォーカスを外す為に、アドレスバーを選ぶ
  • 出来た文字列を選ぶ
  • ゴニョゴニョボタンを押す!
たまーに上手くいかない場合もある
追記1
最後に余計な文字を1個作って、それを選択せずにゴニョゴニョするとよさげ

追記2
ちょっと改良
javascript:var d=document,t,i,l,m=[];l=d.getElementsByTagName('span');for(i=0;i<l.length;i++){if(l[i].className=='hatena-star-star-container')m.push(l[i]);}t=d.createElement('input');t.type='text';t.onblur=function(){var v=d.createElement('div');v.innerHTML=' '+t.value+' ←ここまで選択';m[0].appendChild(v);m[0].removeChild(t);};m[0].appendChild(t);void(0);

追記3
あ、それでもダメな時があるね...
パターンがつかめない...orz

2007/09/28

はてな

ローカルDBやメモリDBとして使えるSQLiteは、開発者にとってかなり有用なツールです。 私はよく「あーーーあのSQLどう書こう」なんて悩む時にSQLiteのshell版を使います。今日はそのWin32 SQLite3のshell版sqlite3.exeの作り方をご紹介。

まず、ダウンロードページから
sqlite-3_5_0.zip
というファイルをダウンロードします。
次に、ソースツリー内の「src」ディレクトリに移動し、以下のMakefileを置きます。
.SUFFIXES: .c .obj

all : sqlite3.exe

sqlite3.exe :  alter.obj analyze.obj attach.obj auth.obj btree.obj build.obj callback.obj complete.obj date.obj delete.obj expr.obj func.obj hash.obj insert.obj legacy.obj loadext.obj main.obj opcodes.obj os.obj os_os2.obj os_unix.obj os_win.obj pager.obj parse.obj pragma.obj prepare.obj printf.obj random.obj select.obj shell.obj table.obj tokenize.obj trigger.obj update.obj utf.obj util.obj vacuum.obj vdbe.obj vdbeblob.obj vdbeapi.obj vdbeaux.obj vdbefifo.obj vdbemem.obj vtab.obj where.obj mutex.obj mem1.obj malloc.obj
    cl /Fesqlite3.exe alter.obj analyze.obj attach.obj auth.obj btree.obj build.obj callback.obj complete.obj date.obj delete.obj expr.obj func.obj hash.obj insert.obj legacy.obj loadext.obj main.obj opcodes.obj os.obj os_os2.obj os_unix.obj os_win.obj pager.obj parse.obj pragma.obj prepare.obj printf.obj random.obj select.obj shell.obj table.obj tokenize.obj trigger.obj update.obj utf.obj util.obj vacuum.obj vdbe.obj vdbeblob.obj vdbeapi.obj vdbeaux.obj vdbefifo.obj vdbemem.obj vtab.obj where.obj mutex.obj mem1.obj malloc.obj

.c.obj :
    cl /c /DSQLITE_THREADSAFE=0 $<
後は、Visual Studioのコンパイラにパスが通ってるならば「nmake」でコンパイルします。 なおSQLiteは、内部処理がUTF-8でやり取りされており、Win32版の場合はNTかどうかでCreateFileA/CreateFileW等、ワイド文字APIの呼び方を変えています。
しかし、コマンドライン引数には対応出来ておらず
C:¥> sqlite3.exe データベース.db
なんて事すると、エラーが発生します。ちなみにNTでない場合には変換無しにCreateFileAを使いますから問題なく動きます。
これって、コマンドラインをUTF-8にすれば動くんだろうけど
C:¥> chcp 65001
やってUTF-8にしても文字は化けるし、IME動かないし意味無いですよね。
適当に
--- os_win.c.orig   Mon Sep 03 22:39:38 2007
+++ os_win.c    Fri Sep 28 22:17:50 2007
@@ -137,6 +137,8 @@
 # define isNT()  (1)
 #else
   static int isNT(void){
+    if( GetACP() != CP_UTF8 )
+      return FALSE;
     if( sqlite3_os_type==0 ){
       OSVERSIONINFO sInfo;
       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
こんなパッチ当てて、実行すると日本語のファイル名も扱える様になります。
このEXEをUSBなんかで常備しておくと、いざという時に助けられるかもしれませんね。


はてな
はてなブックマークは、はてなブックマークだからしょうがないのです。
はてブ批判をすると、何故か釣りと言われる
よく考えてみよう。書き逃げのネガティブコメントを行った場合、その人は発言に責任を負わなくなってしまう。それはよくない。電車での痴漢と同じである。

idも明記されているしpermalinkもあるはてなブックマークコメントを「書き逃げ」と感じる理由がよく分からない
公開の場にテキストを書くという意味ではblogと何ら変わらない責任が発生すると思っています。

普通の人にとっては書き逃げだと思います
管理人とコメンテーターとは、とても対等とはいえないと思います。管理人はコメントを承認制にしたり、削除したりできるし。逆にコメンテーターは、邪魔臭いコメントを大量に書いて嫌がらせすることも可能です。

続きを読む...


2007/09/27

はてな
# telnet baka-kyoudai.com 80
GET / HTTP/1.0
Host: baka-kyoudai.com:80
User-Agent: Anchan/0.1 (compatible; IKARIYA 6.0; DRIFTERS 5.1)

兄:ドンドンドン!ドンドンドン!
弟:「誰だ?」
兄:「あんちゃんだよ。お前のあんちゃんだよ」
HTTP/1.1 401 Unauthorized
Server: Apache-Drifters/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Thu, 01 Jan 1970 09:00:00 JST
WWW-Authenticate: Basic realm="Resource Of Brothers"
Content-Type: text/html;charset=utf-8
Content-Length: 979
Date: Thu, 27 Sep 2007 12:48:36 GMT
Connection: close
...
弟:「ほんとに俺のあんちゃんか?」
兄:「ほんとにあんちゃんだよ」
弟:「それじゃあ、これに答えてみろ。電車に必要なのは乗車券、飛行機に必要なのは搭乗券、じゃあ映画に必要なのは?」
GET / HTTP/1.0
Host: baka-kyoudai.com:80
User-Agent: Anchan/0.1 (compatible; IKARIYA 6.0; DRIFTERS 5.1)
Authorization: Basic dGFrYWt1cmE6a2Vu

兄:「高倉健」
HTTP/1.1 200 OK
Date: Thu, 27 Sep 2007 12:55:21 GMT
Server: Apache-Drifters/1.1
Content-Length: 176 Content-Type: text/html;charset=utf-8

...

弟:「あっ、あんちゃんだ! 入れよ入れよ」
Posted at 22:21 in web | WriteBacks (0)
Tagged as: ドリフ
Bookmarks: add to hatena add to hatena | add to del.icio.us add to del.icio.us | add to livedoor.clip add to livedoor.clip | add to buzzurl add to buzzurl | add to fc2bookmark add to fc2bookmark | add to Yahoo Bookmark add to Yahoo Bookmark | add to Pookmark add to Pookmark | add to NiftyClip add to NiftyClip | この記事へのリンク

はてな
はてなスターの☆をクリックする度に画面を鮮やかに彩るグリモン書いた」は好評で、はてなスター日記でも取り上げて頂きました。
ただ、はてなブックマークでは、「Internet Explorerの為見れない」といったコメントを頂きました。

現在、Hatena Beautiful Starは
  • Firefox
  • Opera
  • Safari
にて動作確認をさせて頂いておりますが、実はInternet Explorerでも動かせない訳ではありません。

続きを読む...


はてな
どこでもスターグリースモンキーを公開しました
はてなスターをさまざまなサイトに付けられる「どこでもスター」グリースモンキーを公開しました。
http://s.hatena.ne.jp/js/HatenaStarEverywhere.user.js
また、同時にさまざまなサイトの設定情報を共有できるSiteConfigWikiもオープンしました。
http://s.hatena.ne.jp/siteconfig
どうぞご利用ください。
よく出来てる。AutoPagerizeのSITEINFOのように、サイト管理もはてなpre記法で書け、色んなサイトに対応出来るように見える。

でもこれって、「○○○のサイトに、はてなスターが付けられるグリモン書きました!」って事が出来なくなるんですよね。
ハッカー殺しとは言いませんが、以前「[再考]twitterが何故ウケるのか?」という記事で書いたように、良いサービスというのは

少しでも開発者が介入できるスキがあるか

が決め手だと私は信じている。

あと細かい話だが、上記引用部にあるリンクのsiteconfigで記述出来るセレクタは、Ten.jsというライブラリを使ったCSSセレクタを採用しており、XPathの様に柔軟ではない。
例えば、IDもCLASSも振られていないノードの、2個次のノードにスターを付けたいとか、そのノードの親ノードを辿りたい場合には、向かない。

現に、このsiteconfig自身にはてなスターを付けられるように考えて見たが、ノード階層が <h2><a href="hosturl">hostname</a><h2>
<div class="section-menu">
    ...
</div>
<div class="section">
    <pre>
    ...
    </pre>
</div>
となっており、IDもCLASSも付けられていないh2要素をエントリ郡として扱う為には、h2と書くしかない。これによってスターを付けるcontainerにはa要素を指定するしか無くなり、結果スターをクリックした瞬間にa要素が反応してしまう事になる。
まぁ、これはsiteconfig自身の問題で、h2要素からdiv要素までを纏めるdiv要素を作って貰えれば対応出来る話だが、XPathなら既存のHTMLでもまったく問題ない。

出来る事ならば、Web::Scraperの様にXPathもCSSセレクタも両方使える様にするのがいいんじゃないかなと思った。


2007/09/26

2007/09/25

はてな

アルファって何だ?

アルファブロガーって何だ?

アルファギークって何だ?

アルファブックマーカーって何だ?


はてなダイアリーキーワードによると
アルファブロガー あるふぁぶろがー
多くの読者に読まれている、影響力のあるブロガー。
しかし英語圏ではこの言葉は定着せず、代わりに「Aリストブロガー(A-list blogger)」という表現が用いられるようになっている。

アルファギーク あるふぁぎーく
「産業を変化させる力を持つ新しい技術に早いうちに飛びつき、ああでもないこうでもないといじくっているうちに、技術が進むべき方向性を示し始める、先鋭的で飽きっぽいエンジニア」(Tim O'Reillyの定義による)。

アルファブックマーカー あるふぁぶっくまーかー
SBMを用いていろいろやってる人たち。
との事。
なんか最近「アルファ」の使い方が、あちこちでずれてる気がする。
「すごい」とか「定評のある」とかで「アルファ」を使ってる人も見る。これってちゃんと定義された物なんじゃなかろうか...

だったら...

昨日、家に帰ってからウチの近所の中じゃぁ「アルファ女房」でもある嫁が作ってくれた、アルファ手料理を頂いた。
家族にも定評のある、「アルファ肉じゃが」で晩酌してると、横で子供がウルトラマンアルファのフィギュアで遊んでた。
なんだかアルファ懐かしくなった。

テレビでアルファ芸人「大島よしお」のギャグ「タンポポ関係ねぇ」を見てたら、眠くなってきたので風呂に入った。
その後仕事してたら、アルファネットウォーカーでもある友人からメールが来て
「お前のブログ、無断リンク禁止だったよな?なんかアルファブックマークされてるぞ」
と教えてもらった。
急いで見たら、アルファブックマークの他に、アルファコメンテーターから複数のコメント、しかもアルファスターが付いてる。
アルファブックマークなんかされたら、もうおしまいだ。明日にもブログを閉じよう。

こんな使い方を肯定している事になる。いかんな。こりゃ。


#なんかアルファ無意味な記事だな、コレ


はてな
こういう使い方もあるね。
で、どうする...って訳でもないけど
※そういうの、「使い道ない」っていうんだよね。そうだよね。
#!/usr/bin/perl

use strict;
use warnings;

use Web::Scraper;
use URI;
use YAML;

my $airlines_accident_scraper = scraper {
  process '//div[@class="entry-content"]//table/tr',
    'airlines[]' => scraper {
      process '//td[1]', title => 'TEXT';
      process '//td[2]', last_accident => 'TEXT';
      process '//td[3]', flight_count => 'TEXT';
      process '//td[4]', death_accident => 'TEXT';
      process '//td[5]', death_rate => 'TEXT';
      process '//td[6]', accident_incidence => 'TEXT';
      process '//td[7]', total_rank => 'TEXT';
    };
  result 'airlines';
};

my $list = $airlines_accident_scraper->scrape(URI->new('http://www.manji.com/jp/2007/08/post_22.html'));
use YAML;
warn Dump $list;
リストは、マスコミが報じない危険な航空会社リストから拝借。

余談ですが...
Web::Scraper 0.16あたりから、@参照するとstringでなく、URIか返ってくるようになってるので、「認証付きのページで@srcを拾い上げて、認証無しでは参照出来ない画像を落とす」なんて事に使えるようになったみたいです。

2007/09/20

はてな
Web::Scraper 0.15とcisco_scraper.pl
問題が一つ。添削してくださったパッチだと
process '//li/node()[4]', 'title' => sub {$_->string_value;};
となっているのですが、4番目とは限らないんです。
たとえば、
http://www.cisco-records.co.jp/html/item/004/010/item393180.html
は何曲か試聴サンプルがないために、この処理だと取得できないです。
おろろ...
これはtext()でTextNodeを参照するしかないですね。
ただ、text()では改行等のゴミまで拾ってしまうので、以下のようにnormalize-space()で空文字ノードを省いています。
もしかすると、node()[2]も同じように修正した方がいいかもしれませんね。
#!/usr/bin/perl

use strict;
use warnings;

use Web::Scraper;
use URI;
use YAML;
use Data::Dumper;

my $uri = shift;

my %scraper;

$scraper{'link'} = scraper {
    process 'a', 'name' => 'TEXT';
    process 'a', 'uri'  => '@href';
    result qw/name uri/;
};

$scraper{'genre'} = scraper {
    process '//a[1]', 'top'   => $scraper{link};
    process '//a[2]', 'style' => $scraper{link};
    result qw/top style/;
};

$scraper{'track'} = scraper {
    process '//li/text()[normalize-space(.)!=""]', 'title' => sub {
        my $s = $_->as_XML;
        $s =~ s/\s+$//;
        return $s;
    };
    process 'li>a', 'uri' => '@href';
    result qw/title uri/;
};

$scraper{'item'} = scraper {
    process 'td.de_title',      'title'  => 'TEXT';
    process 'td.de_artist',     'artist' => 'TEXT';
    process 'td.nm_jacket>img', 'image'  => '@src';
    process 'td.de_price',              'price'   => 'TEXT';
    process 'td.de_label>a',            'label'   => $scraper{link};
    process 'td.de_genre',              'genre'   => $scraper{genre};
    process 'td[headers="de_format"]',  'format'  => 'TEXT';
    process 'td[headers="de_release"]', 'release' => 'TEXT';
    process 'td[headers="de_country"]', 'country' => 'TEXT';
    process 'td[headers="de_sheet"]',   'sheet'   => 'TEXT';
    process 'td[headers="de_arrival"]', 'arrival' => 'TEXT';
    process 'td[headers="de_nomber"]',  'number'  => 'TEXT';
    process '//p[@class="de_star"]/node()[2]', 'star' => 'TEXT';
    process 'ul[id="de_sound"]>li', 'tracks[]' => $scraper{track};
    result
        qw/title artist image price label genre format release release country sheet arrival number star tracks/;
};

my $item = $scraper{'item'}->scrape( URI->new($uri) );
warn Dump $item;
あと、ブックマークコメント
コールバック渡しだと相対URLの展開がされないのは僕だけ?
との事ですが...少し調べてみた所Web::Scraper側でパッチが必要かもしれません。
以下svn/trunk(rev2351)からの差分です。
Index: lib/Web/Scraper.pm
===================================================================
--- lib/Web/Scraper.pm  (revision 2351)
+++ lib/Web/Scraper.pm  (working copy)
@@ -152,12 +152,12 @@
         local $_ = $node;
         return $val->($node);
     } elsif (blessed($val) && $val->isa('Web::Scraper')) {
-        return $val->scrape($node);
+        return $val->scrape($node, $uri);
     } elsif ($val =~ s!^@!!) {
         my $value =  $node->attr($val);
         if ($uri && is_link_element($node, $val)) {
             require URI;
-            $value = URI->new_abs($value, $uri);
+            $value = URI->new_abs($value, $uri)->as_string;
         }
         return $value;
     } elsif (lc($val) eq 'content' || lc($val) eq 'text') {