本を読む

読書やコンピュータなどに関するメモ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

「カムイ伝」1~15巻

 言わずと知れた白土三平の名作マンガ。ふと思って改めて通読した。やはり傑作。

 テーマは江戸時代の身分制度によって苦しむ人々の姿で、封建領主や商人(資本家)に対して主人公たち農民が団結するという話。社会主義の教科書と呼ばれたというのもわかる気がする。

 ただ、そう教条的にまとめてしまうのも惜しい。

 普通のマンガや小説などは、1つか、せいぜい2つぐらいの物語を描いている。主人公しか描けていない作品もあったりする。面白いかどうかとは軸とは別として。

 しかし、本作の場合、多数の多彩な人々が描かれ、人の数だけ物語がある。展開もそれぞれの思惑がからみあって決まっていく。そして、そうした流れが集まって大河のような全体を形づくっている。人だけではなく、動物などの自然まで描いている。

 文学用語では全体小説っていうのだろうか(よく知らない)。一歩間違えれば散漫な失敗作になると思うが、うまく乗り切っているのが凄い。

 さて、次はエンターテイメント寄りに振った「カムイ外伝」を通読するか。

カムイ伝 (1)
カムイ伝 (1)
posted with amazlet on 06.12.31
白土 三平
小学館
売り上げランキング: 1057473
スポンサーサイト

「PLUTO」4巻

 浦沢直樹が手塚治虫の「地上最大のロボット」を元にしたマンガ。

 この巻でこんな展開になるとは…ネタバレになるのでこれ以上は略。

 ネタバレにギリギリならないところでいうと、表紙の人物は碇ゲンドウではなくて天馬博士です。キャラも似てるかな。

 忘れちゃいけない、西原理恵子があとがきを描いてます。

PLUTO 4―鉄腕アトム「地上最大のロボット」より (4)
浦沢 直樹 手塚 治虫
小学館
売り上げランキング: 2

P::P::Filter::RegexpTitle

s_nobuの日記 - 長いタイトルがついたEntryをF::BreakEntriesToFeedsして送る時にGmailでデコードに失敗するのを避けるパッチ
http://d.hatena.ne.jp/s_nobu/20061222/1166748650

例えばこのEntoryの様に長いタイトルがついてる時にF::BreakEntriesToFeedsでuse_entry_title: 1すると、送信者の名前が長くなりすぎてGmailで受信するとデコードしてくれない。

ということで、適当にカットする。40という数字は適当。

 Filterでやったほうが使い回しが効いていいような気がします。

package Plagger::Plugin::Filter::RegexpTitle;
use strict;
use base qw( Plagger::Plugin );
use Encode;

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'update.entry.fixup' => \&filter,
    );
}

sub filter {
    my($self, $context, $args) = @_;

    local $_ = $args->{entry}->title;
    my $regexp = decode_utf8($self->conf->{regexp}, Encode::FB_CROAK);
    my $count = eval $regexp;
    if ($@) {
        Plagger->context->log(error => "Error: $@ in " . $self->conf->{regexp});
        return;
    }
    $args->{entry}->title($_) if($count);
}

1;

 ほとんどP::P::Filter::Regexpのコピペ。

 で。

  - module: Filter::RegexpTitle
    config:
      regexp: s/^(.{40}).*/$1/

「 スノウホワイト」

 諸星大二郎がグリム童話を描くとこうなるという本。出版社は違うが、「トゥルーデおばさん」の続編。

 単に設定を置き換えたとかではなく、原作の要素を残しながら、視点のまったく違う話に仕立てあげているのがさすが。

 しかし、あとがきで作者が書いているように、白雪姫ってそうとうアレな話ですな。

スノウホワイト グリムのような物語
諸星 大二郎
東京創元社
売り上げランキング: 158

technoratiのRSSからWebビーコンを除去

 追跡とかは別にいいけど、RSSリーダーで更新扱いになるのが面倒。というわけで、それPla。Filter::StripRSSAdのasset。

technorati.pat

<img width="1" height="1" src="http://static\.technorati\.com/y/\d+\.gif\?\w+/[\w=]+" />

2007-1-14追記:
Webビーコンのパターンが変わったので、新しいパターンを定義した

やじうまWatchをメールで読む

 先月やった作業。

 やじうまWatchをメールで読もうと思った。それPla。が、そのときPlagger::Plugin::CustomFeed::YajimaWatchのダウンロード先につながらなかったので、車輪を再発明する。CustomFeed::Script+Rubyスクリプトで。

 工夫したのはURLにMD5ハッシュを入れたところ。が、あとでCustomFeed::YajimaWatchを見たらまったく同じことをしていた。

 はまったのは、Rubyのyamlライブラリで日本語がまともに使えないところ。小細工している。

yajiumawatch.rb

#!/usr/bin/ruby -Ku
require 'kconv'
require 'open-uri'
require 'yaml'
require 'digest/md5'

class String                    # from [ruby-list:41779], for YAML bug
  def is_binary_data?
    return true if self.include?(0)
    check = self[0, 512]
    check.size < 10 * check.count("\x00-\x07\x0b\x0e-\x1a\x1c-\x1f")
  end
end

url = 'http://internet.watch.impress.co.jp/static/yajiuma/'

re = %r|<P>
<B>(.*?)</B>
<BR>
(.*?)
 *<BR><DIV align=right><FONT size=-1>(.*?)</FONT></DIV></P>|

feed = {
  'title' => 'やじうまWatch',
  'link'  => url,
  'entry' => [],
}

open(url) {|io|
  io.read.delete("\r").toutf8.split(/<HR noShade SIZE=1>/).each {|d|
    %r|<B><FONT color="darkblue" size="\+1">【?(\d+)/(\d+)/(\d+)】</FONT></B>| =~ d or next
    date = Time.mktime($1, $2, $3).strftime('%Y-%m-%dT00:00:00')
    d.scan(re){|title, body, author|
      feed['entry'].push({
        'title'  => title,
        'body'   => '<p>' + body + '</p>',
        'author' => author,
        'date'   => date,
        'link'  => url + '#' + Digest::MD5.hexdigest(title), # dummy URL
      })
    }
  }
}
print feed.to_yaml.gsub(/\\x([0-9A-F]{2})/){ [$1].pack('H*') } # for YAML bug

2007-01-27追記:
正規表現を2文字ほど変更

P::P::CustomFeed:cbook24を更新

 Plaggerを使ってcbook24の近刊情報をRSSやiCalにするためのプラグイン P::P::Customfeed::cbook24を更新したので晒しておく。

 変更点はこんな(↓)ところ。

  • HTMLの形式の変更に対応した
  • PlaggerにHTMLでデータを渡すようにした
  • iconもつけてみた。icon対応のPublishプラグインなら使える模様
  • その他、普通に書き方をいろいろ変更
  • package Plagger::Plugin::CustomFeed::cbook24;
    use strict;
    use base qw( Plagger::Plugin );
    
    use Encode;
    use Plagger::UserAgent;
    use Plagger::Util qw( decode_content );
    
    our $VERSION = '0.02';
    
    sub register {
        my($self, $context) = @_;
        $context->register_hook(
            $self,
            'customfeed.handle' => \ handle,
        );
    }
    
    sub handle {
        my($self, $context, $args) = @_;
    
        if ($args->{feed}->url =~ m|^http://www\.cbook24\.com/bm_browsing\.asp|){
            return $self->aggregate($context, $args);
            return 1;
        }
    
        return;
    }
    
    sub aggregate {
        my($self, $context, $args) = @_;
    
        my $url = URI->new($args->{feed}->url);
        my $agent = Plagger::UserAgent->new;
    
        my $feed = Plagger::Feed->new;
        $feed->title('cbook24');
        $feed->link($url);
    
        my $re_next = decode('utf-8','\<a\s+href="([^"]*)">\s*次  へ nbsp;\s*\</a>');
    
        PAGE: {
    	my $content = Plagger::Util::load_uri($url);
            $content =~ s/[\r\n]/ /g;
    
            $content =~ m|$re_next|o and my $nexturl = URI->new_abs($1, $url);
    
            $content =~ s/.*?\<td vAlign="bottom">//;
            $content =~ s/\<td valign="top" align="right" width="150">.*$//;
    
            my @items = split(/\<td align="center" valign="top" width="50%">/,
    			  $content);
            foreach my $item (@items){
    	    my $entry = parse_item($item, $url);
                $feed->add_entry($entry);
            }
    
            if($nexturl){
                $url = $nexturl;
                redo PAGE;
            }
        }
        $context->update->add($feed);
    }
    
    sub parse_item {
        my $item  = shift;
        my $url = shift;
    
        my $re_date = decode('utf-8','発売日:.*?(\d{4}/\d+/\d+)');
        $item =~ m|$re_date|o or next;
        my $date = Plagger::Date->strptime('%Y/%m/%d', $ );
    
        $item =~ m|\<a\s+href="(.*?)"\s+title="(.*?)">| or next;
        my $itemurl = URI->new_abs($1, $url);
        my $itemtitle = $2;
    
        $item =~ m|<img[^>]*src="(/assets/product_images/[\dX-]+\.jpg)">| and
    	my $icon = { url => URI->new_abs($1, $url) };
    
        $item =~ s|\</table>.*||s;
        $item =~ s|\</tr>|\n|g;
        $item =~ s/[ \t]+|<.*?>//g;
        $item =~ s|\n|<br />|g;
    
        my $entry = Plagger::Entry->new;
        $entry->title($itemtitle);
        $entry->link($itemurl);
        $entry->date($date);
        $entry->body('<p>' . $item . '</p>');
        $entry->icon($icon) if($icon);
    
        $entry;
    }
    
    1;
    __END__
    
    =head1 NAME
    
    Plagger::Plugin::CustomFeed::cbook24 - Custom feed for cbook24 booklist
    
    =head1 SYNOPSIS
    
      - module: Subecriotion::Config
        config:
          feed:
            - url: http://www.cbook24.com/bm_browsing.asp?page=0 browsing%5Ftype=comingsoon
      - module: CustomFeed::cbook24
    
    =head1 DESCRIPTION
    
    This plugin creates a custom feed from cbook24 book list.
    
    =head1 AUTHOR
    
    Masakazu Takahashi
    
    =head1 SEE ALSO
    
    L<Plagger>, L<http://www.cbook24.com/>
    
    =cut
    

    LinuxでWiiリモコン

     先週、WiiリモコンでLinuxを操作できるかなと試して、週末に仲間にデモした。すでに内容が古くなっている気もするけど、古くなりすぎる前にメモとしてまとめておく。


     WiiリモコンでWindowsを操作するためのプログラム「WiiRemote」が窓の杜などで紹介され、インターネット上で話題になった。

    窓の杜 - 【NEWS】“Wiiリモコン”をパソコンの無線マウスとして使えるようにする「WiinRemote」

     Linuxでもできないだろうかと思っていたところ、WiiリモコンでLinuxのX.orgを操作するためのプログラムが公開された。以下、試した結果をレポートする。

     なお、以下の内容は2006年12月9日時点のもので、wiimotulator.pyのバージョンが0.0.3.9のときの記録だ。wiimotulator.pyは毎日バージョンアップされているようなので注意。

    Wiiリモコン

     ユーザーからは、以下の3つの系統で入力を受け取る。

    ボタン
    方向ボタンや「A」「B」ボタンなどのボタン。
    加速度センサー
    CMでやっているアレ。
    ポインタ
    ディスプレイのところにセンサーバーを付けて、リモコンが画面上を指している位置を検出。実はセンサーバーには2か所に赤外線LEDがあるだけなので、ピンポイントの赤外線源が2つあればよい。

     本体とはBluetoothで通信する。ボタンなどの指示を本体に送るほか、本体からバイブレーターのオンオフなどのコマンドを受け付ける。

    wiimotulator.py

     ブログのエントリーに案内があり、wiimotulator.py.txtがダウンロードできる。これをwiimotulator.pyにリネームして使う。ちなみに、12月7日に、私もこのブログにコメントしてる。

    Robots w/Lasers Control X.Org cursor with Wiimote

     と思ってたら、その後、公式サイトもできた模様。

    WMD FTW

     「ドライバ」とうたっているが、実際はbluetoothからの情報を受け取ってLinuxやXのイベントを発生させるユーザープログラム(Pythonで書かれている)。bluetoothを扱うにはPyBluez(bluetooth.py)を、LinuxやXのイベントを発生させるにはuinput(/dev/input/uinput)とpython-xlibを使う。

     ボタンとポインタに対応している。加速度センサーは、読み取るところまではできているが、LinuxやXのイベントへの割り当てはされていない。

     ちなみに、個人的に、加速度センサーのデータを調整してX.orgのマウスポインタを動かす改造までは試して、デモした。ただ、すでに古いのでここでは割愛する。

    試した環境

    • PC:ThinkPad X60s
    • OS:Ubuntu Linux 6.06
    • USB接続のBluetoothアダプタ:PLANEX BT-01UDE

    インストールしたパッケージ

     Ubuntuの以下のパッケージをあらかじめインストールした。

    • libbluetooth1-dev
    • python-dev
    • python-xlib
    • python-xlib-doc
    • gnome-bluetooth

     そのほか、bluez-utilsやlibbluetooth1などが入っていなければそれらも必要。

    PyBluezをインストール

    Wiiリモコンのbluetoothアドレスを調べる

    • $ hciutil scan
    • リモコンの電池蓋の中にある同期ボタンを押す
    • ここでNintendoの名前が入ったデバイスが表示されるので、そのアドレスを記録

    wiimotulator.pyの設定

    • スクリプトをエディタで開く
    • MY_WIIMOTE_ADDR=""の行(56行目)で右辺にWiiリモコンのアドレスを指定
    • UINPUT_DEV = "/dev/misc/uinput"の行(59行目)をコメントアウト
    • #UINPUT_DEV = "/dev/input/uinput"の行(60行目)をコメントから出す

    実行

    • $ sudo python wiimotulator.py
    • 「Now trying to discover a willing Wiimote」とメッセージが表示されたら、リモコンの電池蓋の中にある同期ボタンを押す
    • ボタンを押したり、リモコンを振ったりすると、ターミナルにログが表示される
    • geditなどを開いてボタンを押すと、wiimotulator.py中で設定されているキーが押されたのと同じ動作になる
    • 「1」ボタンが左クリック。「2」ボタンは右クリックのはずだが中クリック扱いになる
    • 「home」ボタンで終了

    ポインタを試す

    • 蝋燭を2本用意し、火をつけて、ThinkPadの両脇に立てる(赤外線LEDの代わり)
    • Wiiリモコンを画面に向けてsudo python wiimotulator.pyを実行、同期
    • Wiiリモコンの向きを変えるとX.orgのマウスポインタが動く
    • マウスポインタが思うように動かないのは、蝋燭のせいか?

    「さおだけ屋はなぜ潰れたのか」

     不覚にも笑った、という言葉がぴったりの本。便乗本がこんなにバカでいいのか(←この場合はほめ言葉)。

     ベストセラーを見てすぐ影響されていつも失敗する人物を主人公にした連作ギャグ小説。タイトルどおり、さおだけ屋を始めて失敗したり、「バカの壁」を読んでダイナマイトを爆発させたり、「ウェブ進化論」を読んでガンダーラを妄想したり、「えんぴつで奥の細道」を読んで…とか、くやしいが笑える。

     しかも、元の本について的確に理解したうえでネタにしてるっぽいところがミソ。

     ちなみに表紙はチラシの裏。

    さおだけ屋はなぜ潰れたのか?
    池田 浩明
    竹書房
    売り上げランキング: 16969

    「ウンコな議論」

     詭弁やハッタリなど、嘘ではないけどウンコな議論について分析する哲学書。

     …ただし、その方法は、自らウンコな議論の形式で論ずるというもの。最近の新書のような、自分にかわって悪口を言ってくれる「あるある」系を期待するとハズすと思う。

     ちなみに、1ページあたりの文字数が少なく、さらに正味50ページ。章・節・項分けなし。

    ウンコな議論
    ウンコな議論
    posted with amazlet on 06.12.15
    ハリー・G・フランクファート 山形 浩生
    筑摩書房
    売り上げランキング: 71081

    HTML::Tidyのバージョンでハマる

    Plaggerで作っている勝手Planetが、一部文字化けするようになった。

    HTMLやフィードのソースを見ると、該当部分がヨーロッパ文字として実体参照になっている。Bundle::Planetにある各段をバラしてそれぞれ検証してみると、Filter::HTMLTidyを通したところでヨーロッパ文字化されていることがわかった。

    そこで、P::P::Filter::HTMLTidyと、そこから呼ばれているHTML::Tidyを見比べてみる。HTML::Tidyのほうではnew()のパラメータとしてconfig_fileしか受け取っていないが、P::P::Filter::HTMLTidyではパラメータをどんどん渡している。謎。

    いろいろ調べてみると、自分のところにあるHTML::Tidyは1.06で、調べたときの最新版は1.07_01のようだ。PODを見ると、1.07_01ではnew()のパラメータをいろいろ渡せるらしい。そこで1.07_01をダウンロードしてインストール。無事、文字化けが直った。

    結論は「ちゃんとmake testしよう」ということで。

    多段のP::P::CustomFeed::Simpleを試作

     [Plagger]パイプラインというエントリを読んで、そうそう、掲示板とかをPlaggerでスクレイピングするときに、トピック一覧ページと各エントリのページの2段階になってることがあるんだよな、と思った。

     ただし私の場合、とりあえずCustomFeed::Configが多段になっていればいい。そこで、CustomFeed::Multistageというのを試作。

     使いかたはPODのとおり。Subscription::Configのmeta:で、multistage:の中に各段のfollow_linkまたはfollow_xpathを並べる。まず1行目のfolow_*でCustomFeed::Simpleと同じように処理し、そこで抽出された各URLに対して2行目のfollow_*で処理し…と続く。理論上は何段階でも続けられる。

     ただし注意が必要なのは、最終段の各ページごとにフィードが作られること。まとめて1つのフィードにするには、SmartFeedとか他の段で処理する必要がある。

     実装はなんてことない、Customfeed::Simpleを継承してラッパーとして動き、aggregate()を再帰的に呼び出しているだけ。

    package Plagger::Plugin::CustomFeed::Multistage;
    use strict;
    use base qw( Plagger::Plugin::CustomFeed::Simple );
    
    our $VERSION = 0.01;
    
    sub register {
        my($self, $context) = @_;
        $context->register_hook(
            $self,
            'customfeed.handle' => \&handle,
        );
    }
    
    sub handle {
        my($self, $context, $args) = @_;
    
        my @stagelist = @{$args->{feed}->meta->{multistage}}; # copy array
        my $meta = shift @stagelist;
        $args->{match} = $meta->{follow_link};
        $args->{xpath} = $meta->{follow_xpath};
        if ($args->{match} || $args->{xpath}) {
            $self->aggregate($context, $args) or return;
        }
    
        if(@stagelist){
            my $newfeed = Plagger::Feed->new;
            $newfeed->meta({ multistage => \@stagelist});
            my $newargs = { feed => $newfeed };
            my $oldfeed = pop @{$context->update->feeds};
            for my $e (@{$oldfeed->{entries}}) {
                $newargs->{feed}->url($e->link);
                $newargs->{feed}->link($e->link);
                $self->handle($context, $newargs);
            }
        }
    
        return;
    }
    
    1;
    
    __END__
    
    =head1 NAME
    
    Plagger::Plugin::CustomFeed::Multistage - Simple way to create title and link only custom feeds (multistage version)
    
    =head1 SYNOPSIS
    
      - module: Subscription::Config
        config:
          feed:
            - url: http://www.example.com/hoge/
              meta:
                multistage:
                  - follow_link: archive\d+/date.html
                  - follow_link: msg\d+\.html
    
      - module: CustomFeed::Multistage
    
    =head1 DESCRIPTION
    
    
    =head1 AUTHOR
    
    Masakazu Takahashi
    
    =head1 SEE ALSO
    
    L<Plagger>
    
    =cut
    
    
    1;
    

     | HOME | 

    Categories

    Recent Entries

    Recent Comments

    Recent Trackbacks

    Appendix

    emasaka

    emasaka

    フリーター。
    連絡先はこのへん

    Monthly


    FC2Ad

    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。