2009年12月17日木曜日

memcached client

Javaのmemcached clientはツクダニにするほどあるようだが, SPYMEMCACHEDというのを 使ってみた.並列性に気を遣っているとのことなので.本当かどうかは不明.

memcachedb on Mac Leopard

berkeley DB でパーシステントになった memcached であるところの memcachedbをmac Leopardにインストール.

まずはberkeley DB.デフォルトで入っているというはなしなのだが,どこにあるのかわからず, Oracleから落としてきて普通に入れてみた.version4.8が最新だが,4.7で. UNIX扱いで入る.

libeventは port で.

memcachdb はconfigureの際に--with-libevent=/opt/local とすればOK.

2009年12月13日日曜日

log4j - java.util.logging bridge

log4j の出力を java.util.logging にリダイレクトするためのアペンダを書いてみた.がうまく動かなかったので,ここに捨てておく.いや,動いたには動いたのだが出力がへん. もっといいやり方としては,slf4j を間に挟む方法があるらしい.それをやってみよう.
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

public class JDKLogAppender extends AppenderSkeleton {
    static Map map = new HashMap();
    static Map levelMap = 
      new HashMap ();  
    static {
        levelMap.put(org.apache.log4j.Level.FATAL, java.util.logging.Level.SEVERE);
        levelMap.put(org.apache.log4j.Level.ERROR, java.util.logging.Level.SEVERE);
        levelMap.put(org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING);
        levelMap.put(org.apache.log4j.Level.INFO, java.util.logging.Level.INFO);    
        levelMap.put(org.apache.log4j.Level.DEBUG, java.util.logging.Level.FINE);            
        levelMap.put(org.apache.log4j.Level.TRACE, java.util.logging.Level.FINER);            
    }

    private Logger getLogger(String name){
        Logger logger = map.get(name);
        if (logger != null)
            return logger;
        logger = Logger.getLogger(name);
        map.put(name, logger);
        return logger;
    }
    
    @Override
    protected void append(LoggingEvent event) {
        String loggerName = event.getLoggerName();    
        Logger logger = getLogger(loggerName);
        logger.log(levelMap.get(event.getLevel()), layout.format(event));
    }        

    @Override
    public void close() {
    }

    @Override
    public boolean requiresLayout() {
        return true;
    }
}

2009年12月12日土曜日

html parser for GAE

JavaにはHTML parser はやまほどある.一番簡単なのは,Swing に標準で含まれている javax.swing.text.html.parser.* を使う方法.だが,しかしこのパーザは,GAEでは使えない.swingが丸ごとblack listに入っているせい.実際にはグラフィックを使う部分ではないから この部分には害はないはずなのだけど.

他にもパーザはやまほどある. htmlcleanerと言うものを使ってみたが,いまいちうまくいかない. 原因は,文書内のMETAタグの中のcharsetをちゃんと読んでくれないせい. 本来,HTTPのヘッダに含まれるContent-typeに含まれているべき情報なのだけど, HTTPサーバだって各文書の文字コードのことまでは知らないので,ちゃんと設定するのはむずかしい.なので,METAタグでhttp-equivで書くのが普通. htmlcleanerに渡すReaderを適当な文字コードで作ってやれば読めるのだけど,それには,先に一度文書の中を読んで,METAタグを調べてから,htmlcleanerに食わせてやらなければならない. 面倒だ.

HTML Parser(どうでもいいが,もうすこし個体を識別できる名前をつけてほしい)は,まずは適当な仮定を持ってストリームを読み,meta tagを読み込んだ時点で,仮定と異なる文字コードだった場合には,頭からパーズし直してくれるらしい.

使ってみると確かにちゃんと読めているようだ. EUCのasahi.comもutf-8のwikipedia.jpも何も気にしないで読める. こりゃ便利.ツリーの中のノードに対して適当な条件をつけて,合致するノードだけ返す,なんてこともできる.a タグ で href があるものだけ,という条件で読んでみるとこんな感じ.

parser = new Parser(con);
Parser.getConnectionManager ().setRedirectionProcessingEnabled (true);
NodeFilter filter = 
  new AndFilter(new TagNameFilter("a"), new HasAttributeFilter("href"));
NodeList nodeList = parser.parse(filter);
for (Node node: nodeList.toNodeArray()) {
  TagNode tagNode = (TagNode)node;
  writer.println(tagNode.getAttribute("href"));
  writer.println(getText(tagNode));
}
いわゆるDomとは仕様が違うのが気になるけど,とりあえずこまらないかな.

2009年11月23日月曜日

yaml for java

いくつも実装があるようなのだが,使える物がない...
  • JYamlは,すごく単純なドキュメントでもエラーがでてパーズできない場合がある.理由は不明.最近は更新されていない.
  • JvYamlもエラーがでるらしい.これは試してない.
  • JvYamlb はJvYamlの作者が最近作っている実装らしいのだが,最後のbが示すとおり,byte列のみを扱う.つまり,Javaのオブジェクトになってからも,byte列なのだ.get("xxx") とかすることもできない.勘弁してくれ..
みんなどうしてるんだろう? いろいろためして, YAMLBEANS にたどり着いた.これはいまのところ,期待したように動いてくれているようだ...しかし,需要はありそうなのに決定版がないのが不思議.

2009年11月6日金曜日

VLAN on CentOS

vlanconfigを使う手動法ではなく,自動的にできるようにする方法. ここに詳しく書いてある.

  • /etc/sysconfig/network に下記を追記
    VLAN=yes
    VLAN_NAME_TYPE=DEV_PLUS_VID_NO_PAD
    
  • /etc/sysconfig/network-scripts/ifcfg-ethX.YYY を書く. YYYがタグ.
    DEVICE=ethX.YYY
    BOOTPROTO=static
    ONBOOT=yes
    IPADDR=192.168.100.10
    NETMASK=255.255.255.0
    

2009年10月28日水曜日

pubsubhubbub

パブサブハバブと読むらしい. ホームページ

要するに,RSSのポーリングをノーティフィケーションに置き換える,という話で,間にブローカを置くことで,トラフィックを押さえる,というWeb Servicesの世界でもよく聞くような話.RSS Readerへの配送が早くなる,というが,Google ReaderのようなオンラインのReaderの場合だけで,ローカルなReaderだと別に早くならない.当たり前だが.

JavaFX と JAXB

混乱してきたのでまとめ.
  • JavaFX はJDK1.5 を前提としている.
  • JAXBはJDK6から取り込まれたが,1.5の場合は外部ツールが必要
  • JWSBP2.0にJAXBが含まれている.が,このJAXBも実はJDK6を必要としているようで,コンパイルは通るようになったのだが,実行すると落ちる.

JAXBは,ここからダウンロードできる.

  • JAXB の 2.2をためしてみたが,1.6用のようでだめ.
  • 1.0.6は,逆に古すぎる?のか,クラスファイルのバージョン番号がおかしいと言われてだめ.
  • 2.0.0 にしたら動いた!

これほど面倒な面倒なことになるとは...

JWSDP 2.0

JAXBをJDK5 で使うために,JWSDP2.0を導入. ここからダウンロード.Web startのダウンロードツールを強制的に使わされて不快.

shellアーカイブなのだが,実行するとすてきなインストーラが起動する.~/packages以下にインストール.

~/packages/jwdp2.0/jaxb/bin にjaxbがある.JWSDPにはいろいろ入っているが,用があるのは,JAXBだけなので,この下だけ切り出してもいいかも.

jaxbを使うときに,javaが1.5になるようにPATHを調整する必要がある.

javaFX とJDK6

EclipseのJavaFXのプラグインで,JDK6のクラスを参照したjavaのコードが共存できない.プロジェクトはちゃんとJDK6にしてあってもだめ.

内部的に,javafxpackagerというコマンドを起動しているのだが,これにverboseオプションをつけて実行してみると, なかでjavacを起動するときに,-target 1.5で起動している...なぜだ. 切り替えるオプションもないようだし,JDK5 でやるしかないのか...JAXBのライブラリどうしたらいいんだ??

2009年10月25日日曜日

jetty 組込

Jettyの組込サーバとしての利用法.ここに書かれている. 使い方としては,warのためのディレクトリ構成をつくって,そこを指定してサーバを起動する.

注意点は,

  • jetty7だとパッケージ名が org.eclipse 以下になっている.
  • サンプル中のコンテキストパスは,URLのプレフィックスを決めている模様.

2009年10月5日月曜日

SteerMouse とtrackman fx

PS/2のTrackman marble FX をMacで使いたくて,アダプタ経由でつないでみたが,スクロールがうまくいかない.SteerMouseを試してみたが,やっぱりだめだ.Trackman marble FXは,あるボタンを押すと,ボールがホイール代わりになるという特殊な代物なので,どうにもならないようだ.不思議なことに,firefoxのなかではSteerMouseなしでもスクロールができる(というかスクロールボタンを押した状態になる)のだが,他の窓だとだめ.うーん.残念だなあ...

2009年9月21日月曜日

Servletで 405 エラー

App Engineで405がでてしばらくはまる.

落ちは,doGet を doGETと書いていた...教訓は,

@Override
は伊達じゃない,ってことで.

2009年9月20日日曜日

java-twitter とGAE

java-twitterはApp Engineでは使えない.
org.apache.commons.httpclient.MultiThreadedHttpConnectionManager
を使っているから.

くそー...面倒くさいな..

java-twitterのインストール

twitterのAPIをwrapしたライブラリjava-twitterをインストールしようとしたら,はまったのでメモ.バイナリがダウンロードできるのだが,依存しているjarが全然書かれていないので,一筋縄ではないかない,という...これがmaven時代のjavaプロジェクトのありかたなのか.

前提として,mavenはインストールされていること.適当なプロジェクトを作る.

> mvn archetype:create -DgroupId=com.example -DartifactId=sample
> cd sample
pom.xmlを編集して,下記を追加.レポジトリを追加しているのと,コンパイラのバージョン指定.
  <repositories>
    ...
    <repository>
      <id>java-twitter-repository</id>
      <url>http://java-twitter.googlecode.com/svn/repository/</url>
      <name>java-twitter maven repository</name>
    </repository>
    ...
  </repositories>
...
  <dependencies>
    ...
    <dependency>
      <groupId>net.unto.twitter</groupId>
      <artifactId>java-twitter</artifactId>
      <version>0.9-SNAPSHOT</version>
    </dependency>
    ...
  <dependencies>
...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
で,
> mvn package
> mvn dependency:copy-dependencies -DoutputDirectory=lib
とやるとlibにすべてのjarが集められる.
> cd lib
> ls
commons-beanutils-1.7.0.jar ezmorph-1.0.6.jar
commons-codec-1.2.jar  google-collections-0.9.jar
commons-collections-3.2.jar java-twitter-0.9-SNAPSHOT.jar
commons-httpclient-3.1.jar joda-time-1.6.jar
commons-io-1.4.jar  json-lib-2.2.3-jdk15.jar
commons-lang-2.4.jar  junit-3.8.1.jar
commons-logging-1.0.4.jar protobuf-java-2.2.0.jar
こんなにたくさん...たしかにこれはいちいち書いてられないかも.

2009年9月15日火曜日

OOWebとPOST

OOWebというcherrypyににたサーバフレームワークがある.メソッドをURLツリーにマップして,リフレクションでよびだしてくれてなかなか面白いのだが,どうもPOSTで生データを送ったりするのに対応できないっぽい.formからPOSTする場合のデータはちゃんとハンドルしてくれるのだけど,逆に生のデータがとれないのだ.

メソッドにはRequestStateという引数がわたるのだけど,このRequestStateのなかに生データへアクセスする方法が含まれていないようなのだ.eclipseで止めてのぞいてみたがだめっぽい. ソースをみても,RequestState以外を引数として呼び出すコードはない.ということで多分だめ.うーん,面倒だなあ.やっぱりjettyを使うのか..

2009年8月27日木曜日

NHKのラジオ講座をMacでダウンロード

NHKのラジオ講座は,今年度から前の週1週間分だけ,ストリーミングできるようになった. これはこれですばらしいことではあるが,なんで一週間分なんだ! とか怒りもわいたり. さらに問題なのは,ストリーミングにフラッシュを使っているので,普通にダウンロードすることが できないこと.しかも昨年度の試行では普通にできたのに,わざわざ今年度からできなくしているのだ. こういう嫌がらせにどういう意味を見いだしているのか理解できない.

それはさておき何とかならないか,調べてみると,Windows上には 高梨IT製作所のキャプチャツール というツールがあり,フラッシュをダウンロードしてmp3に変換してくれる. すばらしいのだが,MP3の名前をSJISにしているので,Macにコピーして iTunesに取り込むと文字化けする. コピーするのも面倒.

で,幸いこのツールはRubyで書かれているので,Macで使えるようにしてみた. このキャプチャツールはrtmpdumpという外部プログラムを 使ってflvをダウンロードし, ffmpegを使ってmp3に変換する.なので,これらをMac上に 用意する必要がある.ちなみに,rtmpdumpはadobeの独自プロトコルをリバースエンジニアリングして 作った物のようで,ちょっとグレイかもしれない.

ffmpegは

sudo port install ffmpeg
で入る.rtmpdumpのほうはソースからコンパイルする.このときopensslが必要なので,
sudo port install openssl
でopensslを導入し,rtmpdumpのメイクファイルを編集し,CFLAGSとC++FLAGSに
-I /opt/local/include
を,LDFLAGSに
-L /open/local/lib 
を追加しておく.これでmakeすると rtmpdump_x86 というバイナリができる.これを 適当なパスにコピーしておく.

キャプチャツールにはCUI版とGUI版がある.CUI版のほうを使う. ここ からダウンロードできる. ZIPを展開すると,トップディレクトリにget-flv.rbがある. このなかで,rtmpdumpとffmpegのバイナリを指定している場所があるので 適当に書き換える.id3も指定しているが,使っていないようなので無視.

ファイル名がSJISになっているのは,わざわざSJISにしているから. lib/get_flv.rb に何カ所か tosjis を呼んで部分があるが, それらを全部削除. これで,完成.

ruby get-flv.rb kor
とやると,mp3/kor に日本語名でファイルがつくられる. iTunesに入れても文字化けしない. すばらしい.

2009年7月28日火曜日

netstat

TCPでリッスンしているポートを表示
netstat -t -l
さらに
netstat -t -l -p
とするとpidとプログラム名が表示されるけど,sudoしないと自分のプロセス以外は表示されない.

2009年7月24日金曜日

linux container ホスト,ゲスト通信

Linuxコンテナでは,ゲスト上で任意のジョブを実行することができない.vserver だとできるのだが.ネットワークをちゃんと設定してsshでやればいいのだが,macvlanを使う場合にはなかなか面倒らしい. で,いろいろ試してみたら,FIFO (名前付きパイプ) で通信できることがわかった.ゲストのファイルシステム上にFIFOをつくればいい.簡単.

2009年7月17日金曜日

VMware serverのコマンドラインからの制御

ここにいろいろ書いてある.VMのIDは16,32,といくようだ.ひょっとして48を指定すると,16と32が同時に制御できるのか?
 vmware-vim-cmd vmsvc/getallvms   - リスト取得
 vmware-vim-cmd vmsvc/power.on 16
 vmware-vim-cmd vmsvc/power.off 16
 vmware-vim-cmd vmsvc/power.reboot 16

2009年6月26日金曜日

bash リダイレクト

いつもわからなくなるbashのリダイレクト.ここに詳しい.

標準エラーと標準出力を同じファイルに.

  command > file 2>&1 
標準エラーと標準出力を同じパイプに
  command 2>&1 | command2

2009年6月22日月曜日

Log4Jの制御

Log4Jの出力ストリームをプログラム内部で制御 ここを参考に.
WriterAppender appender = 
   new WriterAppender(new PatternLayout("%d [%t] %-5p %c - %m%n"), outstream);
Logger.getRootLogger().addAppender(appender);
で,出力先を他のストリームに変更することができる.

2009年5月22日金曜日

ubuntu 9.04 jaでのflyspell mode

emacsのflyspell-modeがうまく動かなかった.理由は
  • そもそもaspellの英語辞書が入っていなかった.
  • 日本語環境だと日本語に対してスペルチェックしようとして日本語の辞書を探しにいく.
aspell-en を入れ,
LANG=C emacs
で起動すればOK.

2009年5月19日火曜日

Xen で wake up on LAN

いろいろ試してみたがどうにもうまく行かない.サーチしてみたら こんなページを見つけた.

何かバグらしいのだけど,よくわからない. ここに置いてあったパッチを,手元のCentOS 5.0, Xen 3.0に手作業で当ててみたのだけど,うまくうごいてくれなかった.むーん,なにがいけないんだろうか.

Eucalyptus のネットワーク

意外に面倒.というかすごく面倒...Rocksの中だからということもあるのだけど. そもそもRocksのフロントエンドのDHCPDはRocksの管理下にあるので, いじると何が起こるのか(私には)分からない.が,どのモードもDHCPDをいじる必要があるみたいなんだよな...面倒.

可能なネットワーク設定は次の4種.

  • SYSTEM Mode
  • STATIC Mode
  • MANAGED Mode
  • MANAGED-NOVLAN Mode

SYSTEM Mode

最も単純.ユーザがDHCPを起動しておき,Eucalyptusのインスタンスはそれを利用する.環境によっては何も考えずに簡単に導入できそうなのだが...

STATIC Mode

DHCP サーバはEucalyptusが管理する.使用するMAC Address とIPaddressのペアを設定ファイルに書いておくと,Eucalyptusがそれらをラウンドロビンで利用する.

SYSTEMもSTATICも,各VMコンテナのネットワークをブリッジして使う.これだと,RocksでインストールしたプライベートIPのクラスタでは,外から入れない.

MANAGED Mode

プライベートIPのレンジを割り当て,そこをEucalpytusが管理するDHCPDが使う.この場合もアドレスはプライベートでルーティングできないのだけど, パブリックIPアドレスのプールを用意して尾家,ルーティングするように指定するころができる.

MANAGED-NOVLAN Mode

MANAGEDとほとんど同じだが,内部でVLANをつかわないので,インスタンスの通信が分離されない.
さて,どれを使ったものやら...

2009年5月14日木曜日

Condor on Etch 86_64

すくなくともCondor 7.3 は etch用には86のバイナリしか無い.つまり86_64版がない. これでも動くはずなのだが,libsspが無いと言われて動作しない.これには32bit用のgccをインストールすればいいはずだが,それはそれで面倒くさい.

RHEL3,86_64版を持ってきたところ,これはこれでlibstd++.so.5がないと言われて動かない. http://packages.debian.org/etch/amd64/libstdc++5/downloadからdebを持ってきてインストールしたところ動作するようになった.めでたい.

2009年5月8日金曜日

ubuntu 9.04 trackman marble fx

どうも最近のXorgはxorg.confをちゃんと読んでくれていない?マウスの設定はhalが認識してしまうらしい。で、trackman marble fxがうまく動いてくれないので、 こちらを参考に、 こんな/etc/hal/fdi/policy/mouse-wheel.fdi を書いてみた。マウスの名前は/var/log/dmsgに出ていたもの。
<match key="info.product" string="PS2++ Logitech Mouse">
<merge key="input.x11_options.EmulateWheel" type="string">true</merge>
<merge key="input.x11_options.EmulateWheelButton" type="string">8</merge>
<merge key="input.x11_options.XAxisMapping" type="string">6 7</merge>
<merge key="input.x11_options.YAxisMapping" type="string">4 5</merge>
<merge key="input.x11_options.ZAxisMapping" type="string">4 5</merge>
<merge key="input.x11_options.Emulate3Buttons" type="string"<true</merge>
</match>
スクロールが動くようになった。めでたい。

2009年5月3日日曜日

Wake up on LAN

職場の実験用クラスタに常に火が入っているのがもったいないのでWake up on LANを設定してみた.必要なことは下記.
  1. 対象マシンのBIOSでWake up on LANを設定する
  2. 対象マシンのOSからインターフェースカードにWake up on LANを指定する
  3. 対象マシンに対してマジックパケットをブロードキャストするプログラム
はまったのは2.そんな設定が必要だと思っていなかった. LINUXの場合,ethertool というものをつかえばよい. ここここにあるように,
yum install ethtool
echo 'ETHTOOL="wol g"' >> /etc/sysconfig/network-scripts/ifcfg-eth0
とやればよい.初回は
ifconfig eth0 down; ifconfig eth0 up
しないとこの設定が有効にならないので注意.
3のプログラムは, ここ からとったものを使った.macaddressの書き方に寛容で便利.

2009年4月22日水曜日

Mac OS X Leopard で VNC

LeopardにはScreen SharingというVNCクライアントが入っている.safariで
vnc://address:port
とやるとつながる.ここでportはVNCとしての番号ではなくて5901などのポート番号.

わたしのように普段safariを使わない人の場合は,terminalから

> open vnc://address:port
とやっても同じ.便利.

2009年3月31日火曜日

CentOS で埋め込みビットマップを使わない

デスクトップに入れたCentOSでフォントをいれても,なんかレンダリングが汚いとおもっていたら,埋め込みビットマップが使われているせいだったらしい.Ubuntuだと大丈夫なのに.いろいろ調べて,/etc/fonts/conf.d/90-nobitmap.confとして下記のファイルをおいておけばよいということが判明.てこづった.しかしこれでデスクトップ画面がすばらしく見やすくなった.うれしい.
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
 <match target="font" >
  <edit mode="assign" name="embeddedbitmap">
   <bool>false</bool>
  </edit>
 </match>
</fontconfig>

2009年3月25日水曜日

python iso8601

bloggerのfeedの時刻情報はISO8601というフォーマットで出てくる.ところがpython標準のtimeモジュールやdatetimeモジュールではこれがパーズできない.正規表現を使ってかかなければ行けないのか,面倒だなあ.と思っていたところ,こんなものを見つけた.

すばらしい...ありがたいことだ.っていうかtimeモジュールのパーザ異常に弱い.Cの標準ライブラリに頼っている都合らしいが,もう少しなんとかしてくれ.

2009年3月17日火曜日

google docs からダウンロード

docs に置いたファイルをスクリプトで処理するためにダウンロードする方法を調べた.

ここにあるgadatacopierを使う.このプログラムは,pythonで書かれていて,gdata APIのpython clientを使う

Python Clientはここからダウンロードする.展開するとsetup.pyがあるのでこれをsudoで実行すればインストールされる.インストールしたくなければ,srcをPYTHONPATHに加えればいい.

PYTHONPATH=$DIR/gdata.py-1.2.4/src $DIR/gdatacopier-1.0.2/gdoc-cp.py\
 --username $NAME --export csv --google-id $ID --local $OUT

最初に試したときには,ひとつ問題があって,うまく動かなかった.この問題らしいので,ここに書かれている通りに.encode('UTF-8')をコメントアウトしたら動くようになった。

def _get_item_list(self, item_type = None):
    .....
    item_list.append({'title': entry.title.text,#.encode('UTF-8'),
こんなハックでいいのかね.

2009年3月16日月曜日

RADEON HD4350で WQXGA

手元にあったこのグラフィックボードをDELLの3008をつないだのだが,解像度が十分でない.Dual Linkがサポートされていないのか,とかいろいろ考えたのだが,単にドライバの問題だった.

ここからダウンロードする.shell archiveになっているので,sudo sh xxxx.runで実行する.で,Xを再起動すればOK. しかし,実売5000円しないようなグラフィックボードで,WQXGAがドライブできるのだなあ...

2009年3月4日水曜日

gnuplot で積み上げグラフ

これで書ける.ちゃんとフィルされる.4.2じゃないとだめらしい.
set style data histograms
set style histogram rows
set yrange [0:]
set style fill solid 1.0 border -1
set boxwidth 0.9 relative
plot 'testdata' using 2, '' using 3, '' using 4, '' using 5
データはこんな.
1 0  10 12 18
2 1  11 13 19
3 1  12 14 20

2009年2月28日土曜日

google spreadsheet のダウンロード

このドキュメントによれば httpのGETで簡単に取得できるようだ.

curl https://spreadsheets.google.com/feeds/download/spreadsheets/Export?key=ID&fmcmd=FOMAT

が,認証がかかっているとリダイレクトされてしまう.認証の方法はこちらにかかれている.後でやってみよう.

2009年2月15日日曜日

Giftag

http://www.giftag.com/. BestBuy傘下のサービス.これはAmazonの「欲しいものリスト」のようなものだが,特定のサイトに閉じていないのが特徴.つまり任意のサイトのデータが利用できる.

基本的にはhProductという標準XMLフォーマットのデータを用いているサイトが対象で,このデータを持ってくるようなのだが,このフォーマットをサポートしていない場合にはそれなりになんとかしてくれるようだ.

で,これはGoogle App Engine上に実装されているらしい.ちゃんとスケールするということの証明になっているのだろうか.

2009年2月12日木曜日

VMware Fusion 内のIME on/off

Macbook 上のVMware FusionでWindows XPとかLinuxとかを使っているのだけど,IMEの on/offのキーアサインが違っていて発狂寸前.でいろいろがんばってみた.ホストのMacbook状ではCmd+Spaceを使っているので,Windowsのほうをこれに合わせる.

WindowsのIMEのon/offのアサインはツールを使わなくても結構自由に変えられる.「テキストサービスと入力言語」でIMEを選んでプロパティを開く.「全般」の「キー/ローマ字/色の設定」の「設定」を開くとキーバインドが出てくるのでここで指定すればいい.CmdキーはVMware上のWindowsではWindows-keyして認識されているので,Windows-key + spaceが設定できればいい. ところが,ここでWindows-key + Spaceは指定できない.というかWindows-keyは一般的なmodifierとして認識されていないらしく,Windows-key関連はここではまったく使えない.

私はWindows-keyのないthinkpad が長かったので,Windows でWindows-keyを使う習慣がない.なので,Windows-keyは要らない.と考えると話はわりに簡単.とりあえず,shift + spaceをキーバインドとして指定する.で,changekeyを使って,左のwindowsキーをshiftにしてしまう.これで,cmd+spaceでwindowsのIMEがon/offできるようになった.

ちなみにこのように変更しても,当然Mac OS 側には何の影響も無いので,VMwareの画面からCmd+tabで抜け出すことができる.

あとはlinuxだなあ.どうしよう.

2009年2月11日水曜日

latex2html

ではまった.

なぜかページが全然生成されない.原因は改行コードが0dになっていたこと.気の迷いでfileを作るときにeuc-jp-macにしていたのが原因.latexは普通に処理してくれていたので発見が遅れた.まいったまいった.

もう一つ.

latex2html -split 0 xxx.tex
とやると,すべてが1枚のhtmlになる.数ページ程度の文章ならこちらの方が読みやすい.あとwordに貼り込むときもこちらのほうが楽.いままで1枚のhtmlにするために,texのsectionをemacsのマクロで置き換えたりしていたのだが,まったく無駄だった.ちゃんとマニュアル読まないと.

2009年2月7日土曜日

boostで文字列と数字を連結する方法2件

Javaだと文字列と数字の連結は簡単で,
"string" + 1
で"string1"になってくれる.C++の文字列にも+演算子が定義されているのだが,残念ながら文字列との結合しかしてくれないようだ.で,こういう場合どうするかというとstring streamを使うのが定番らしい.
#include <sstream>
using namespace std;

ostringstream oss;
oss << str << 1;
string s0 = oss.str();
streamに一度書き込んで,そこから文字列を取り出すということ.うざい.

lexcal_cast

boostを使うともう少しきれいに書ける.一つは,数字を文字列に変換しておいて,文字列連結演算子で連結する方法.
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;

string s1 = s  + lexical_cast<string>(1);
cout << s1 << endl;
だいぶきれいだが,キャストにかかる文字列が長くてこれはこれでうざい.ちなみに実装としてはstring stream を使っているらしい.

format

formatをつかってもいい.これはCのprintf的なフォーマットを実現するもの.関係ないが,ヘッダファイルだけで実現されている.どうやってフォーマットをパーズしているんだろうなあ..
#include <boost/format.hpp>
using namespace std;
using namespace boost;

string s2 = (format("%1%%2%") % str % 1).str();
cout << s2 << endl;
%演算子で区切って引数を渡す構造.面倒なことに%演算子の優先順位が<<などより弱いので,括弧でくくらないとへんなことになったり.

どれで書いてもあんまりすっきりしないなあ.なんで文字列に他の型を結合できるように演算子が定義されていないんだろう?

2009年2月4日水曜日

libcurl のfileプロトコル

libcurlではhttp以外にもいろんなプロトコルが使えるようになっていて,当然fileも使える.が,httpでは動くcontent-lengthだけを取るやり方がうまく動かない.

HEADERとNOBODYを指定して,performしたあとで,CONTENT_LENGTH_DOWNLOADを取ると長さが分かる.

  curl_easy_setopt(dwHandle, CURLOPT_URL, url);
  curl_easy_setopt(dwHandle, CURLOPT_HEADER, 1);
  curl_easy_setopt(dwHandle, CURLOPT_NOBODY, 1);
  curl_easy_setopt(dwHandle, CURLOPT_WRITEFUNCTION, &func);
  curl_easy_perform(dwHandle);
  curl_easy_getinfo(dwHandle, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &dSize);
httpの場合は,head メソッドを使ってcontent-lengthだけ取得しているのだろう.fileの場合はstatでとればいいのでさらに簡単なはずなのだが.

しかたがないのでソースをダウンロードして追ってみると,ちゃんとstatはしている.にもかかわらず,外のプログラムからアクセスできる構造体に設定していないようだった.ので,そこだけちょっと修正したら,動いているっぽい.

とりあえず,MLでレポートしておいたが,さてどうしたものか.CURLにパッチ当てなければ動かないのではソフトとしてリリースできないしなあ...

2009年1月29日木曜日

const member function

関数が引数を変更しないときにはconstを引数に付ける.
void func(const string & str) ;
これはstrで参照されるオブジェクトをfuncが変更しないという意味になる.

メンバ関数の場合には,引数以外にも変更することの可能なオブジェクトがある.暗黙裏に渡されるthisである.このthisを変更しないという宣言をするには const を後ろに付ける.

class A {
  void func(void) const;
}
なぜかというと前に付けると,返り値がconstである場合と区別がつかないから.ああ,面倒くさい.

AtomフィードのURL

ブラウザのアドレスバーの右側にでるRSSフィードマークを出す方法.
<link rel="alternate" type="application/atom+xml" title="Atom" href="atom.URL" />
もしくは
<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="URL" />
head内に書くのがポイント.同じサーバ上にある必要すらない.リダイレクトしようかと思っていたのだけどその必要も無かった.

2009年1月28日水曜日

boost regex でURIパーズ

boost のregular expression library を使って URIをパーズ.こちらのページを参考に.ただちょっと古いようでreg_expression -> basic_regexと読み替えてやる必要がある.

しかし,テンプレートを使ったC++のライブラリの出すエラーメッセージは解読不能だ.1カ所ちょっと使うクラスを間違えただけで,みっしり数百行もエラーが出るのはどうなんだろう? 気の弱いプログラマなら卒倒しかねないぞ.しかもエラーメッセージを見てもまったくエラーの原因がわからないし.やっぱりtemplateは好きになれないなあ.まあ理解不能なメッセージという意味では,latexも似たようなものだが.

#include 
#include 
/**
 *  assumed URI
 *  scheme://[user@][host][:port]/[path][?query][#fragment]
 */
class URI {
public:
  std::string scheme;
  std::string authority;
  std::string user;
  std::string host;
  int         port;
  std::string path;
  std::string query;
  std::string fragment;

  URI(std::string s) {
    static const char * pattern = "\\A([^:]+)://"   // scheme
      "((?:([^:/@]*)@)?([^:@/]*)(?::(\\d+))?)/"   // authority = [user-info@]host[:port]
      "([^\\?]*)(?:\\?([^#]*))?(?:#(.*))?\\z";    // body = [path?query#fragment]

    static const boost::regex e(pattern);
    boost::smatch match;
    regex_match(s, match, e);
    this->scheme    = match[1].str();
    this->authority = match[2].str();
    this->user      = match[3].str();
    this->host      = match[4].str();
    this->port      = atoi(match[5].str().c_str());
    this->path      = match[6].str();
    this->query     = match[7].str();
    this->fragment  = match[8].str();
  }
};

C言語 の配列リテラル

配列を直接初期化してCのプログラム中に書くことができる.こんな感じ.
int A[] = {1, 2, 3};
昔は,グローバル変数か,main関数の中でしか初期化つきで宣言できない,とかいう実装が透けて見えるような制約があったように記憶しているのだけど,gccの4だとごく普通に関数の中でも宣言できるようだ.

で,この書き方は変数の初期化にのみ使えて,例えば関数呼び出しの引数に直接書くことはできない.

void foo(int x[]){}
...
foo({1, 2, 3}); // syntax error

int A[] = {1, 2, 3};
foo(A);         // OK
以前から面倒な仕様だと思っていたのだが,調べてみたらいつの間にか直接書く方法ができていた.
void foo(int x[]){}

foo((int []){1, 2, 3});
見通しは悪いけど,一度変数を宣言するよりはだいぶまし.

これは手元のgcc 4.xで試して動いたというだけなので,どの範囲のコンパイラでサポートされているのかは不明.C90あたりで入っていたんじゃないかと思うので,ほとんどのコンパイラで使えそうだけど.

2009年1月25日日曜日

Mac OSとlinuxの EOF エラーハンドルの違い.

lessのように追記されるファイルから次々に読み込む場合,一度EOFが帰ってきたものに対してスリープして,再度読み込みを行ったりする.が,このときの挙動がlinuxとMac OSで違っていてはまった.
  while (1) {
    char * p = fgets(buf, 1000, fp);
    if (p == NULL) {
      sleep(1);
    } else {
      printf("%s\n", p);
    }
  }
このずさんなコードはlinuxやSolarisだとちゃんと動いて,ファイルに追記されると追従することができるのだが,Mac OSでは動かない.ファイルに追記しても,ずっとfgetsがNULLを返す.

ストリームの中にはすでにEOFに当ったという情報が保持されているのだけど,これを明示的にクリアしてやらないと,いけない,ということのようだ.もっとお行儀のいいコードはこんな感じ.そもそもNULLで返ってきたときに,EOFなのかエラーなのかをferrorでちゃんと見てやって,EOFのときだけ,clearerr()でクリアしてやる.こうするとMac OS でもちゃんと動く.

  while (true) {
    char * p = fgets(buf, 1000, fp);
    if (p == NULL) {
      if (ferror(fp)){
        printf("error, abort\n");
        break;
      }
      clearerr(fp);
      sleep(1);
    } else {
      printf("%s\n", p);
    }
  }
この違いは,きっとSys V系(Linux, Solaris)とBSD系(Mac OS X)に由来する違いなんだろうなあ...

2009年1月24日土曜日

Mac OS ar の COMMAND_MODE

通常の端末からはビルドできるC++のシステムが,eclipseのCDTからだとビルドできないので調べてみた.いちどarで.aを作っておいて,さらにldでリンクするようになっているのだけど,ldのところでこんなエラーがでてこける.
ld: in XXXXX.a, archive has no table of contents
arのほうはこんなふうにかかれている.
ar aruv xxx.o xxx.o ..
arのバイナリは同じものが起動されていることはwhich等で確認できる.

とりあえずの解決

tableがarchiveに入っていないというエラーなので,強制的にtableを作るオプション's'を与えると,とりあえずビルドできるようになる.
ar asruv xxx.o xxx.o ..
しかし's'がデフォルトで, tableを作らないようにするためには'S'で明示しなければならないはず.環境変数でも見ているのかとおもって,マニュアルを見ても何も書かれていない.

もう少し調べてみる

バイナリをstringsで見てみる.最後に怪しいものが...
$ stings `which ar`
...
COMMAND_MODE
legacy
eclipseの中で確認してみるとたしかにこのCOMMAND_MODE環境変数がlegacyに設定されている.端末ではunix2003になっている.
$ echo $COMMAND_MODE
unix2003
$ COMMAND_MODE=legacy make
とやってlegacyを指定してビルドするとeclipse内と同じように失敗する.これが原因であることはほぼ確定.つまり,legacyが指定されているとarのデフォルトの挙動が変わるのだろう.問題はなんでこんなものが指定されているのか,だ.

ググってみたら一番上にこんなページを見つけた.推測でしかないのだが,eclipseはMac OS 10.4でも動くようにビルドされているので,launchd が起動時に識別して付けているのではないか,という話.うーん...

ちなみに,arのstringsでunix2003が引っかからないことからも予想できるように'legacy'以外なら何が指定されていてもちゃんとテーブルが生成される.

どう対処するのがただしいのか分からないのだけど s オプションは,他の環境でも付いていて害があるものではないので,かならずこれを付けるという方向で.

2009年1月23日金曜日

Doxygen

javadocのようなドキュメント作成ツール. ホームページ.サポート言語は
C++, C, Java, Objective-C, Python, IDL (Corba and Microsoft flavors), 
Fortran, VHDL, PHP, C#, and to some extent D
だそうだ.すごいね.手元のubuntuにはなぜだか入っていた.入れた記憶はないのだが. 出力フォーマットもゆたかで,HTML,latex のほかに,RTF (MS-Word), PostScript, hyperlinked PDF, compressed HTML, Unix man pageをサポート.

使い方

doxygen -f conf
とやると巨大なコンフィギュレーションファイルができる.デフォルトではhtmlとlatexができるようになっている.当面latexはいらないので,
GENERATE_LATEX  = yes
をno に変更.PROJECT_NAME にプロジェクトの名前を,INPUTに入力ファイルのあるディレクトリを指定.何も指定しないと,カレントディレクトリのみになる.EXTRACT_ALLをyesにしとくと,コメントの無いクラスもドキュメントを作ってくれるので最初はyesにしたほうがいいかもしれない.

で,

doxygen conf
でOK

ドキュメントの書き方

C++の場合,クラスやメソッドの前にスラッシュ3つで始まるコメントとして書く.ほかにもJavaDocスタイルとか,いろいろな書き方をサポートしているようだ.
/// this is a class
class a {
public:
  /// this ia a method
  void b();
};
これでOK. 便利.

Pythonの場合は,Python 標準のドキュメントの書き方でOKらしい.

2009年1月21日水曜日

sudo とfile descriptor

親子プロセス間で通信するためにpipeを使うのはよくある方法だが,sudo を使うとこれがうまく行かない.おそらくsudoが対象コマンドにexecする前に3番以上のディスクリプタを全部クローズしているんだろう.0, 1,2は閉じていないようなのでこれらを使うしかなさそうだ.

面倒.

CentOS5 python 2.6

with statement が使いたいということで,2.6を入れてみる. 手順はここに書かれている通り. 2.6はともかくそろそろ2.5は標準のレポジトリに入っていてもいいとおもうのだけど.

2009年1月7日水曜日

Codesynthesis XSD

Codesynthesis XSD. いわゆるxsd スキーマからC++のオブジェクトを生成することができるシステム. JavaのJaxbに相当するものだと思われる.面白いのはオブジェクトツリーを作る コードの他に,SAX的な(でももっと簡単に使える)ストリームパーザを生成するコードも 生成するらしいこと.

ライセンス

以下は,私の解釈.

GPL.生成されたコードもGPL.なのだが,例外条項がもうけられていて, XSDの機能に対して十分な付加機能がある場合に限っては, XSDおよび生成されたコードを含んだコードを 他のオープンソースライセンスで公開することが可能になっている. さらに,それをその後proprietaryな製品に転用することも可能.

スタイルファイルを整備

改行が br に変換される設定だったのを直して,スタイルファイルをいじった.その結果以前書いたものがめちゃめちゃになったので,手でタグを入れるという地味な作業.

随分読みやすくなった.書く気がおきるというもの.

bjam on ubuntu

いろいろはまってしまったが、 apt-get一発で入るようだ。bjamは独立したパッケージになっているが、それだけ入れてもだめなのがポイント。
sudo apt-get boost-build
設定としては、ホームディレクトリにuser-config.jamファイルを作り下のように書く。ポイントはgcc と ; の間を開けておくこと。どうもパーザが貧弱なので、トークン切り出しがうまくできていないようだ。
using gcc ;

プログラムを用意

test.hpp をtest.cppとmain.cppが共有。

test.hpp

void test();
test.cpp:
#include "test.hpp"
void test() {}
main.cpp
#include "test.hpp"
int main(){
    test();
}

Jamroot ファイルを書く

: は引数間の区切り. つまりrule exe は2引数で、第一引数がターゲットバイナリ名、第二引数に、ソースファイルのリストをとっている。
exe main : main.cpp test.cpp ;

実行

$ bjam
...found 13 targets...
...updating 6 targets...
MkDir1 bin
MkDir1 bin/gcc
MkDir1 bin/gcc/debug
gcc.compile.c++ bin/gcc/debug/main.o
gcc.compile.c++ bin/gcc/debug/test.o
gcc.link bin/gcc/debug/main
...updated 6 targets...
できた。test.hppにタッチするとちゃんと依存関係を認識していて再度コンパイルする。
$ touch test.hpp
$ bjam
...found 13 targets...
...updating 3 targets...
gcc.compile.c++ bin/gcc/debug/main.o
gcc.compile.c++ bin/gcc/debug/test.o
gcc.link bin/gcc/debug/main
...updated 3 targets...
すばらしい。。。

2009年1月6日火曜日

wordpress DB_HOST 書式

wordpress でmysql 接続にunix domain socketを使う場合wp-config.phpに
define('DB_HOST', 'localhost:XXXX');
のように書く.XXXXのところにはパスを書くのだが,これを間違って名前だけ(mysql5.sock)など書くと,なにもエラーが出ずにデフォルトのmysqlソケットに接続してしまうようだ.エラーがでないので気がつくのが遅れて被害拡大.くそー.

2009年1月2日金曜日

pythonのregular expressionで置換

import re
pat = re.compile('aaa.*?aaa', re.DOTALL)
subst = 'aaa --- aaa'
replacd = pat.sub(subst, target)
  • re.DOTALL は'.'が改行にもマッチするように.
  • .*? の '?'は最短マッチ.

firefox 3.0 のワナ

下のようなコードで
   var contentsNodes = document.getElementsByClassName("contents");
   contentsNodes.each( function(node) {
         xxxx
   });
each is not a function というエラーがでる.googleで検索してこのページを見つけた. getElementsByClassNameをfirefox3.0以降が独自実装したため,返ってくる型がprototypeのenumerableでなくなってしまったということらしい.余計なことをしてくれるなあ.prototypeのバージョンが上がれば大丈夫になるんだろうか?

2009年1月1日木曜日

Google Reader を使ったfeed のaggregate と mixi 設定

Google Readerを使って複数のfeedを一つにまとめることができる.
  • フォルダを一つ作り,まとめたいものをそこに入れる.
  • 設定 の フォルダとタブ のタブで,そのフォルダを「公開」に設定
  • 右側に ページへのリンクができるのでそこをクリック
  • ページの右にatomフィードへのリンクができているのでそのURLを取り出す
  • mixi の外部日記のrssにこのURLを登録
とりあえず動いているようだ.

mixi 日記のバックアップ

というか外部ブログに切り替えるので取り出し.
http://milk-tea.que.jp/milk-cake/soft/
のbackup_mixiをつかわせていただく.

rubyで書かれたツール.ちゃんとスロットリングしながらひとつづつダウンロードしてくれる.スロットリングしないとアタックだと判断されてアクセスが停止されるかららしい.適当にタイムアウトしてリトライするようにできていたり,いろいろと芸がこまかい.

日記だけでなくメッセージもダウンロードしてくれるしマイミクさんのアイコンまで..よくできている.

blogger のバックアップ

wget -O - http://hidemon-memo.blogspot.com/feeds/posts/default?max-results=1000 > filename
でatom形式でダウンロードできるようだ.文字だけだから時間も全然かからない.