« September 2007 | Main | November 2007 »

2007.10.29

[iPod touch]iPod touch (iPhone)用にGNUツールをクロスコンパイルする

iPod touchを、よりUNIXな感じで使いたいので頑張ってみました。

現時点ではLeopardでは問題が出るとのことで、Mac OS X Tigerで作業しました。
なお、iPhoneToolchainv05.dmgがintel向けバイナリで構成されているので、これを使う限りはPPCなMacでは試せません。悪しからず。

手順1: iPod touch / iPhone用のネイティブアプリの開発環境の構築

基本的に、「Native IPhone development using XCode, at last!」に書いてあります。iPhone toolchain のインストールとTipsも参考にしましょう。

前提として、Xcodeのインストールが必須です。

1)iPhoneToolchainv05.dmgをダウンロードしてきてインストール。同梱の「Ooo Shiny!!」は、「/usr/local/arm-apple-darwin/bin/」にPATHを通すために.profileに記述を追加するシェルスクリプトです。それを実行してもいいのですが、僕は手動で~/.bash_profileに追加しました。

1.5)arm-apple-darwin-gcc-4.0.1のシンボリックリンクをarm-apple-darwin-gccとして張っておきます。

sudo ln -s /usr/local/arm-apple-darwin/bin/arm-apple-darwin-gcc-4.0.1 /usr/local/arm-apple-darwin/bin/arm-apple-darwin-gcc

2)iPhoneのシステムソフトウェア1.1.1をダウンロードします。

3)iPhone1,1_1.1.1_3A109a_Restore.ipswの実体はzipなので、拡張子を変えるなどで解凍します。(Safariの場合は、最初から拡張子zipが付いてダウンロードされてきました)

4)vfdecryptをダウンロードし、解凍します。

5)iPhone1,1_1.1.1_3A109a_Restore.zipを解凍して出来たフォルダにvfdecryptをコピーします。

6)ターミナルから上記フォルダにcdした後、次のコマンドを実行します。

./vfdecrypt -i 022-3602-17.dmg -o iPhone_1.1.1.dmg \
-k f45de7637a62b200950e550f4144696d7ff3dc5f0b19c8efdf194c88f3bc2fa808fea3b3

7)iPhone_1.1.1.dmgをダブルクリックしてマウント。以下を実行してイメージ上のファイルを/usr/local/arm-apple-darwin/heavenly以下にコピーします。

sudo mkdir /usr/local/arm-apple-darwin/heavenly
sudo cp -Rn /Volume/Snowbird3A109a.UserBundle /usr/local/arm-apple-darwin/heavenly

8)Xcodeのテンプレートをダウンロードします。

9)解凍し、「iPhone UIKit Application/iPhoneApp.xcodeproj」をXcodeで開きます。

10)Foundation.frameworkとUIKit.frameworkが赤字で表示されているはずです。パスが違っているので、それぞれを選択した後、Command + Iで情報ウインドウを開き、「選択...」ボタンを押して「/usr/local/arm-darwin-apple/heavenly/System/Library/Frameworks」とたどり、それぞれ選択します。「/usr」は普通ファイルオープンダイアログからは見えないので、Command+Shift+Gを押して「フォルダへ移動」のダイアログを出し、「/usr」と指定して確定するとその先がたどれます。

11)「iPhone UIKit Application/Info.plist」を開き、項目"CFBundleExecutable”を“«PROJECTNAME»”に書き換えます。

12)「iPhone UIKit Application」フォルダを「/Library/Application Support/Apple/Developer Tools/Project Templates/Application/」にコピーします。これでXcodeで「新規プロジェクト」を作成する際のテンプレートの中のApplicationセクションに「iPhone UIKit Application」が現れるようになります。

13)以下のように実行します。subversion(svn)をインストールしておく必要があります。

cd /usr/local/arm-apple-darwin/arm-apple-darwin
sudo mv include include-old
sudo svn co http://svn.berlios.de/svnroot/repos/iphone-binutils/trunk/include/ include
sudo ln -s /System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Headers \
/usr/local/arm-apple-darwin/arm-apple-darwin/include/CoreGraphics
sudo ln -s /System/Library/Frameworks/CoreServices.framework/Frameworks/CFNetwork.framework/Headers \
/usr/local/arm-apple-darwin/arm-apple-darwin/include/CFNetwork

ここまでで、iPhone UIKit Applicationはビルドできるようになっているはずです。
Xcodeで「iPhone UIKit Application」のプロジェクトを作り、そのままビルドして通ればまずは安心。

「プロジェクトのフォルダ/build/Release」にappが出来ているはず。これをiPod touch / iPhoneにコピーして実行してみます。その際は、例の「chmod -Rf +x /Applications」で実行権を付けておくことを忘れずに。

ここにあるサンプルのプロジェクトがビルドできれば間違い無しです。

手順2: GNUツールをコンパイルするために必要なarm-apple-darwin-binutilsをインストール

ここまでの手順ではarm-apple-darwin-ldなどのbinutilsが無いため、RubyなどのGNUなツールがコンパイルできません。
MacPortsからarm-apple-darwin-binutilsをインストールします。MacPortsをインストールしていなければ、まずはそれをインストールします。

1)MacPorts-1.5.0-10.4.dmgをMacPortsのページから落としてきてインストールします。

2)「/opt/local/bin/」にPATHを通します。

3)MacPortsの方のディレクトリに、さきほどiPhoneのファイルをコピーしたheavenlyディレクトリのシンボリックリンクを作成します。arm-apple-darwin-binutilsのインストールプロセスで必要になるためです。

ln -s /usr/local/arm-apple-darwin/heavenly /opt/local/arm-apple-darwin/heavenly

3)portコマンドでarm-apple-darwin-binutilsをインストールします。

sudo port install arm-apple-darwin-binutils

4)「/opt/local/arm-apple-darwin/bin」にPATHを通します。ここまでで僕の.bash_profileのPATHのところはこんな感じです。

export PATH=/opt/local/arm-apple-darwin/bin:/usr/local/arm-apple-darwin/bin:/usr/local/bin:/opt/local/bin:$PATH

ただ、このままではいささか問題アリです。なぜなら、「/opt/local/arm-apple-darwin/bin」「/usr/local/arm-apple-darwin/bin」を見れば分かりますが、「gcc、ld」といった感じでアーキテクチャのPREFIX無しでネイティブコンパイラやbinutilsと同名のコマンドが入っているからです。だからこそ、iPod touch向けのコンパイルを失敗したくない今は、パスの順序をこのようにしました。「gcc、ld」みたいな素の名前のやつは、PREFIXを付けてネイティブなツールとかぶらないようにするか、作業時にパスの優先度を切り替えるか。ここは後で整理の予定です。

実践: nkfのコンパイル

これでGNUなツールのコンパイルができるようになっているはずなので試してみます。
試行錯誤しながらだったので、手順が抜けていたらご指摘願います。
さて、日常よく使っているnkfをコンパイルしてみます。iPod touch上でどう使うかはこれから考えます。 :-)

UTF-8 対応 nkf (nkf_utf8)からnkf205.tar.gzをダウンロードしてきます。「tar xvzf nkf205.tar.gz」で解凍し、Makefileを編集。以下の当該項目をこのように書き換えます。

CC = arm-apple-darwin-gcc
CFLAGS = -fsigned-char -v -Wl,-syslibroot,/usr/local/arm-apple-darwin/Heavenly -O

終わったらmakeします。

make
strip nkf

ちゃんと動作しているようです。

実践: wgetのコンパイルと名前解決の問題

今度はGNU wgetをコンパイルしてみます。

tar xvzf wget-1.10.2.tar.gz
cd wget-1.10.2
CC=arm-apple-darwin-gcc CFLAGS="-fsigned-char -v -Wl,-syslibroot,/usr/local/arm-apple-darwin/Heavenly" ./configure --host=arm-apple-darwin --prefix=/opt/iphone
make
strip src/wget
make install DESTDIR=.

ただし、この手順で出来たwgetは名前解決ができません。wickedpsyched.netDNSのページに書いてありますが、iPod touch / iPhoneのusr/lib/libc.dylibに含まれるgethostbyname()がおかしく、普通にコンパイルすると、これが使われることになって名前解決できないようです。つまり、wgetにとどまらずgethostbynameを使うものに共通の問題ということになります。

SafariやMobileMail.appではもちろん名前解決できるので、ネイティブアプリでは別のライブラリを使っているようです。

前述のDNSのページにあるlibresolv.a(こちらにも関数gethostbyname()が含まれる)を使ってコンパイルすると名前解決できるようになるようで、実際それを使ったと思われるworking ping (new resolver)は、ちゃんと名前解決してくれます。
libresolv.aのgethostbyname()を優先的に使わせる方法がありましたら教えてください。CFLAGSに「-lresolv」を付けたりDNS の謎に書いてあるLD_PRELOAD方式もダメでした。ちなみに、libresolv.aからlibresolv.soを作る場合は、以下のようなオプションになりました。Darwinのgccに「-shared」というオプションは無いので「-bundle」に置換。「-read-only-relocs」の代わりに「-read_only_relocs」(アンダーバー)。

arm-apple-darwin-gcc -read_only_relocs suppress -bundle -Wl,-syslibroot,/usr/local/arm-apple-darwin/heavenly/ -o libresolv.so *.o

Installer.appからダウンロードできるDNS Tools(gethostbyname()問題対策済み)をインストールし、それに含まれるhostコマンド等を使うとホスト名からIPが引けるので、当座のしのぎ方としては以下のようなことをやっています。

SITE=www.google.co.jp
wget `host -t A $SITE | sed -n '/[^0-9][^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\)/{s//\1/;p;q;}'`

iPod touch (iPhone)上でバッククオートは入力できないようなので、気合いでどうにかします。
ただ、こうしても再帰取得、リンクをたどってダウンロードする際に絶対リンクが出てくると名前解決しなければならなくなるので、そこで止まります。「-L」オプションなどで相対リンクのみをたどる動作にするといいでしょう、というか、どなたかlibresolv.aのgethostbyname()を使うようにコンパイルする方法を教えてください。

実践: Rubyのコンパイル

rubyもコンパイルできました。

tar xvzf ruby-1.8.6-p111.tar.gz
cd ruby-1.8.6-p111
cross_compiling=yes ac_cv_c_bigendian=no ac_cv_func_getpgrp_void=yes ac_cv_func_setpgrp_void=yes CC=arm-apple-darwin-gcc CFLAGS="-fsigned-char -v -Wl,-syslibroot,/usr/local/arm-apple-darwin/Heavenly" ./configure --host=arm-apple-darwin --prefix=/opt/iphone
make
make install DESTDIR=.

しかし、Installer.appからインストールできるRuby同様、動作が不安定です。

# echo "#!/opt/iphone/bin/ruby" >test.rb
# echo "require 'time'" >>test.rb
# echo "puts Time.now" >>test.rb
# chmod +x test.rb
# ./test.rb
/opt/iphone/lib/ruby/1.8/date/format.rb:963: [BUG] Segmentation fault
ruby 1.8.6 (2007-09-24) [arm-darwin]

zsh: abort ./test.rb

参考ナマケログ: iPod touchでRubyを使うのはちょっと厳しいかも

ちなみに、topするとこんな感じ。

MemRegions: num =  2068, resident = 23.2M +    0B private, 27.2M shared
PhysMem:  23.6M wired, 29.6M active, 11.2M inactive, 64.4M used, 17.9M free
VM:  181P +    0B   7694(0) pageins, 0(0) pageouts

PID COMMAND %CPU TIME #TH #PRTS #MREGS RPRVT RSHRD RSIZE VSIZE
269 top 8.2% 0:17.92 1 17 47 552K 528K 0B 3.38P
222 sh 0.0% 0:01.26 1 13 31 316K 1.38M 0B 4.92P
221 dropbear 0.0% 0:02.79 1 9 25 124K 576K 0B 1.50P
183 sftp-serve 0.0% 0:03.10 1 14 30 244K 400K 0B 1.73P
182 dropbear 0.0% 0:04.56 1 9 25 156K 576K 0B 1.63P
164 notificati 0.0% 0:01.02 2 21 50 260K 500K 0B 1.77P
163 afcd 1.8% 0:09.47 1 15 51 736K 508K 0B 3.36P
143 MobileSafa 0.0% 0:09.55 6 95 227 7.65M 18.6M 0B 49P
72 MobileMail 0.0% 0:03.68 4 119 212 2.42M 14.3M 1.11P 18P
28 notifyd 0.0% 0:03.15 2 156 25 216K 316K 0B 1.64P
26 mediaserve 0.0% 0:14.41 14 145 172 1.23M 1.88M 1.68P 6.64P
25 ptpd 0.0% 0:02.71 2 55 71 484K 1.74M 0B 3.94P
24 update 0.0% 0:16.38 1 13 20 108K 284K 0B 1.08P
23 syslogd 0.0% 0:11.90 3 35 28 212K 340K 0B 1.69P
22 lockdownd 0.0% 0:05.24 4 53 79 648K 1.14M 117T 5.19P
21 mDNSRespon 0.0% 0:02.00 2 45 47 368K 668K 0B 3.08P

搭載メモリ64MBのLinux Zaurusでは、Emacs動かした上に、さらにRubyを動かしても何とかなるんですけどね。Pythonはそんなことなさそうなんだけど。仮想メモリが動いてないんでしょうか?

2007.10.28

[Mac OS X]LeopardではSafari3にてタブがらみのスクリプティングが可能に

Mac OS X Leopardインストールしましたよ。
やはり新しいOSはいい。iMac G5だと、なんかSafariでフォームに入力するときにモタ付きを感じますが。Safari 3 パブリックベータで見られた「っっっっ」という現象は直ってます。

さて、Safari 3 パブリックベータではClassとしては存在しても、まだ機能していなかったタブ(tab)がらみのスクリプティングができるようになっています。

現在Safariは3.0.4。tabの操作をする場合、tell対象はdocumentではなくwindowなのがミソ。

tell application "Safari"
	make new document
	tell window 1
		make new tab
		set myTab to make new tab
		set URL of myTab to "http://www.google.co.jp"
		set current tab to myTab
		delay 5
		close myTab
	end tell
end tell

2007.10.27

[iPod touch]スクリプトをiPod touch (iPhone)用アプリケーションにする方法

もはや説明の必要は無いかと思いますが、ここでの話はJailbrokenな (Jailbreakでアプリケーションをインストール可能にした) iPod touch (iPhone) の存在と、それに関する知識が前提です。

iPod touch (iPhone) でも、Mac OS X同様、シェルスクリプトやその他言語のスクリプトをアプリケーションにできたのでレポートしておきます。

要諦は三つです。

  • Info.plistのCFBundleExecutableに、スクリプト名を指定する
  • スクリプトは、exitもしくはkill $$で締める
  • 実行時の$PATHは/usr/bin:/bin:/usr/sbin:/sbin

一つ目は、通常のアプリケーションで実行ファイルを指定するところでスクリプトを指定するという意味です。

二つ目は、普通に流したスクリプトだと、実行したが最後、終了できなくなってしまいます(この状態からの復帰はHomeボタンを長押しで)。
「exit」もしくは「kill $$」で自分自身をkillするとホーム画面に戻ってこれます。

三つ目。/usr/local/bin、/opt〜などにはパスは通っていないかもしれませんので注意してください。

僕はMac OS Xを使ってますので、plistの編集にはXcode付属のProperty List Editorを使ってます。

サンプルアプリケーションInstBuddy.app

サンプルを作ってみました。

「InstBuddy_0.1.zip」をダウンロード

Instbuddy_2

/var/root/Media/Installに.appをコピーしてから実行すると一発でインストールが完了するという、パッケージになってないアプリケーションをインストールする際に便利なものです。名付けてInstBuddy.app。

中身はシェルスクリプトです。BSD SubsystemとErica's Utilitiesに含まれるコマンドをスクリプト内で使っているので、それらをインストールしておく必要があります。いずれもInstaller.appからインストールできます。

InstBuddy.appのインストール

解凍して出てきたInstBuddy.appをsftp等で/Applicationsにコピーして、実行権を付けます。
iPod touch上のターミナル、もしくはssh経由で以下のコマンドを実行します。

# chmod -Rf +x /Applications

Homeボタンとスリープボタンを長押しして電源オフし、再起動するか、Erica's Utilitiesのインストールが済んでいるならば、iPod touch上のターミナル、もしくはssh経由でrestartコマンドを実行すればインストール完了。

InstBuddy.appの使い方

ホーム画面に現れたInstBuddyを実行します。

すると、「/var/root/Media/Install」というフォルダができるので、そこにインストールしたい*.appをコピーします。
なぜ「/var/root/Media」なのかといえば、iPhoneDiskでマウントできるからです。

再度、InstBuddyを実行します。

Installer.appでインストール/アンインストールを済ませた後同様、自動的にロック状態に移行するので、ロックを解除するとインストールが完了しているはずです。

あとがき

というわけで、InstBuddy.appの実用性はともかく中身を見てみてください。
core.shが実行されるスクリプトです。
Python Scriptなども実行可能かと思います。

2007.10.15

[Mac OS X]iTunes-LAME2.0.9test4の文字化け修正スクリプト

先日のエントリ「[Mac OS X]iTunes-LAMEがiTunes7対応アップデート! しかし……。」で、新しいiTunes-LAME、iTunes-LAME.2.0.9-test4で起きる日本語の文字化けを嘆いたところですが、その文字化けを修正するスクリプトをやっつけで書いてみました。

すぐ修正されるかと思いますが、それまでがまんできない人は試してみてください。

インポートしたMP3にCDからタグをコピーする、ということをやっています。

ダウンロード

「cure-garbled-characters-on-itunes.zip」をダウンロード

使い方

  • ダウンロードしたものを解凍します。
  • CDをインサートし、iTunes-LAMEで曲をインポートします。
  • CDを入れたまま、今iTunes-LAMEでインポートした「ライブラリ>ミュージック」にある曲を選択します。
  • CD上の曲と、「ライブラリ>ミュージック」上で選択中の曲が同じ順番で表示されているか確認します。
  • 「ライブラリ>ミュージック」を表示させます。(CD上の曲を表示させているなら切り替えます)
  • 当スクリプトを実行します。



注意点

無保証です。

  • CDが入っていないとエラーが出ます。
  • CD上の曲数と、「ライブラリ>ミュージック」上で選択した曲数が違うとエラーが出ます。
  • CD上の曲と「ライブラリ>ミュージック」上で選択した曲が同じ順番で表示されていないとエラーが出ます。
  • 「ライブラリ>ミュージック」を表示させていないとエラーが出ます。

間違いが起きてもいいよう、コピーを取ってからやった方がいいかもしれません。

2007.10.12

[Zaurus]ターミナル録画再生ツールttyrec1.0.8のLinux Zaurus向けパッケージ

これからは動画! ターミナルの動画だよ! ということで、高林哲さんのお作りになられたttyrecのLinux Zaurus向けパッケージを作ってみました。
パッケージにはttyrec ttyplay ttytimeを含みます。

ターミナルの操作の模様を録画再生できるツールです。
詳しくはttyrecのサイトを見てみてください。

Linux Zaurusでも、ちょっと変になることはある(?)ものの、動いています。
かなり面白いので、試してみてください。

ダウンロード

「ttyrec_1.0.8-1_armv5tel.ipk.bin」をダウンロード

使い方

パッケージをインストール後、ターミナルを起動します。
僕はUenoさんのカスタムEmbeddedKonsole を使ってます。

ttyrecは80x24固定で使う設計なので、ターミナルのフォントサイズを変更する必要があるかもしれません。80x24より大きければ大丈夫のようです。
「lcfont large」より小さいフォントを選択する必要があります。普通は「lcfont medium」でしょう。
フォントを変更/確認したら、一度ターミナルを再起動してから以下のような感じで実行します。

$ ttyrec -e emacs rec01.tty

すると、この例で行くとemacsの起動プロセスとなりますが、この瞬間から録画が開始されてます。
普通と違うのは、Emacsが80x24の範囲で描画されていることです。
Emacsを終了すると録画も終了となります。

$ ttyrec rec02.tty

上記のように-eオプション無しで実行すると、シェルが起動します。
exitでこのシェルを抜けるまで録画が継続されます。

再生にはttyplayコマンドを使います。さきほどの操作でrec01.ttyというファイルが生成されているので、それを引数に指定すると再生が始まります。

$ ttyplay rec01.tty

ttytimeの引数に録画ファイルを指定すると、その録画時間が秒数で表示されます。

$ ttytime rec01.tty
458 rec01

ttyrecで録画したファイルを以下にアップしておきます。
Linux Zaurus上でEmacsを使っている様子です。

デモ動画

「rec01.tar.gz」をダウンロード

動画の中で使っているtwit.elは個人的に改造したやつなので、emacswikiにあるオリジナルとは違います。

……って「twit.el」をググったら密かに置いてある糞改造twit.elがトップに来てるよwwww
@がうまく動かないからペンディングしてるのにwwwwwww

注意点

ttyrec ttyplayを使った後は、一度ターミナルを終了しないとおかしくなるようです。

展望

ttyrecのデータがいろいろ流通すると面白いんですけどね。
何か録画したら教えてください。

2007.10.09

EAMES Side Shellの脚部ネジ緩み止め

手持ちのEAMES Side Shellのうち、この赤いやつは、Shock Mount部分のネジが、使っていると緩んできてしまう。

このSide Shellは、レプリカのエッフェルベースに付け替えられて売られていたものだが、そのサイズが微妙に合っておらず、無理な力がかかっているからだろう。
もう1脚のフルオリジナルのものは何とも無い。

しばらく緩んだら締めるということを繰り返していたけど、よく見たらワッシャー類が全然入ってない。

平ワッシャーとスプリングワッシャーを(アリモノなのでサイズが合ってないけど)入れてみた。

うーん、なぜこのこのことに気づかなかったか。
接写したら、結構ネジなめてるね。これはきっと奥qあwせdrftgyふじこlp

2007.10.06

[Mac OS X]iTunes-LAMEがiTunes7対応アップデート! しかし……。

いつの間にかGoogle Codeに移管されていたiTunesとLAMEのBridgeであるiTunes-LAMEが久しぶりにアップデート。バージョンは2.0.9に。

iTunes7になってから、リッピングしたファイルのid3-tagに異常が出るようになっていたので、それを直したんだろうとホクホク試してみると、「以前よりは」正常に動作。日本語が化けること以外は……。

ロシアの人が既にプロジェクトページでバグ報告してたので、直ることに期待。
bwandersonという人がWikiの方に「大塚 愛が化けてしまうのは俺にとってチョーでけえ問題ッスよ」って書いてるけど、この人外人だろうか?

というわけで、日本語の文字化けを修正する対策スクリプトを書きました。
スクリプトは以下のエントリに。

[Mac OS X]iTunes-LAME2.0.9test4の文字化け修正スクリプト

2007.10.05

[Emacs]CarbonEmacsからSafariをコントロールする

昨日のエントリ「[Zaurus]Linux Zaurus上のEmacsで選択した単語を「英辞郎 on the Web」で引く」に関連して、CarbonEmacsから手を離すこと無く、裏にあるSafariをコントロールして英辞郎 on the Webをブラウズするための糞Elispを書いてみました。
Elisp -> AppleScript -> JavaScriptの三段重ねですね。

昨日のElispはSafariで一枚もWindowを開いていないときにエラーが出てたので、黙って修正してたりします。


(defun my-safari-do-javascript(command)
(do-applescript
(concat "
tell application \"Safari\"
if count of document is greater than 0 then
do JavaScript \"" command "\" in document 1
end if
end tell")))

(defun my-safari-scroll(direction)
(let ((amount 200))
(if (eq direction 1)
(setq amount (- amount)))
(my-safari-do-javascript
(concat "javascript:window.scrollBy(0,"
(int-to-string amount)
");"))))

;;Safariで上方向スクロール
(defun my-safari-scroll-up()
(interactive)
(my-safari-scroll 1))
;;Shift+上
(global-set-key '[S-up] 'my-safari-scroll-up)

;;Safariで下方向スクロール
(defun my-safari-scroll-down()
(interactive)
(my-safari-scroll 0))
;;Shift+下
(global-set-key '[S-down] 'my-safari-scroll-down)

;;Safariでヒストリを進む
(defun my-safari-history-forward()
(interactive)
(my-safari-do-javascript "history.forward();"))
;;Command+右
(global-set-key '[M-right] 'my-safari-history-forward)

;;Safariでヒストリを戻る
(defun my-safari-history-back()
(interactive)
(my-safari-do-javascript "history.back();"))
;;Command+左
(global-set-key '[M-left] 'my-safari-history-back)

;;Safariでリロード
(defun my-safari-reload()
(interactive)
(my-safari-do-javascript "location.reload(true);"))
;;Ctrl+C r
(global-set-key "\C-cr" 'my-safari-reload)


2007.10.04

[Zaurus]Linux Zaurus上のEmacsで選択した単語を「英辞郎 on the Web」で引く

英語を読み書きする際に、「英辞郎 on the Web」の用例が欠かせない自分用に、Emacsで選択した単語を「英辞郎 on the Web」で引く糞Elispを書いてみました。

「英辞郎 on the Web」はLinux Zaurusには重いんですけどね。Operaだと少しは軽いんでしょうか。

動作に必要な「urlencode.el」

動作にはurlencode.elが必要です。

urlencode.el(今404なのでWebArchiveの直リン)

Linux Zaurus版「英辞郎 on the Webで調べる」

(when (load "urlencode" t)
  (defun my-eijiro(beg end)
	(interactive "r")
	(call-process "qcop" nil nil nil "QPE/System"
				  "execute(QString,QString)"
				  "netfront3"
				  (concat 
				   "http://eow.alc.co.jp/"
				   (urlencode (buffer-substring-no-properties beg end) 'utf-8)
				   "/UTF-8/")))
  (global-set-key "\C-ce" 'my-eijiro))

Mac OS X (CarbonEmacs)版「英辞郎 on the Webで調べる」

(when (load "urlencode" t)
  (defun my-eijiro(beg end)
    (interactive "r")
    (do-applescript (concat "
tell application \"Safari\"
if (count of document) is 0 then
make new document
end if
tell document 1
set URL to \"http://eow.alc.co.jp/"
(urlencode (buffer-substring-no-properties beg end) 'utf-8)
"/UTF-8/\"
end tell
end tell")))
  (global-set-key "\C-ce" 'my-eijiro))

使い方

英語でも日本語でもどっちでもいいので選択したら起動するだけです。
上記から変えていなければ「Ctrl+C e」で起動です。
Linux ZaurusではNetFrontで、Mac OS XではSafariで、選択した単語の「英辞郎 on the Web」の検索結果を表示します。
Safariはあえてactivateせず、SafariのウインドウをCarbonEmacsの隣に開いておく使い方を想定してます。

いっしょに使うと便利なElisp「sense-region.el」

単語を選択するのが面倒臭い。

そんな場合は、「sense-region.el」を使うと、単語のどこかにカーソルが乗ってさえいれば、Ctrlを押しながらスペースキーを二度押すだけで単語の選択が完了します。
さらにスペースを押していくと、後方に向かって単語を一つずつ選択範囲に加えていきます。
物凄く便利なのでおすすめです。

2007.10.03

[Zaurus]Ruby用ライブラリHpricotとWWW::MechanizeのLinux Zaurus向けパッケージ

電車での移動時間を使ってLinux ZaurusでWebのスクレイピングの仕込みをするべく、RubyのHTMLパーサ等を用意してみました。

はけさんのはけのザウルス備忘録別館Hpricotの0.5がありますが、0.6が出ていたのでそれを。
WWW::Mechanizeにも興味があったので、それも。

幾霜の橘さんから「-static-libgcc」というオプションを教わったので、ruby-serialportとruby-termiosをlibgcc(3.4.4)不要版としてパッケージを作り直しました。

いずれのパッケージも、FocVさん版パッケージのRubyの構成に準拠してます。FocVさんのところにある1.8.6-p110を入れた環境で幾霜さんのzgcc34でセルフコンパイルしてます(Pure RubyなWWW::Mechanizeを除く)。

ダウンロード

Hpricot 0.6
「ruby-hpricot_0.6-1_armv5tel.ipk.bin」をダウンロード

WWW::Mechanize 0.6.10
「ruby-mechanize_0.6.10-1_armv5tel.ipk.bin」をダウンロード

ruby-serialport 0.6
「ruby-serialport_0.6-2_arm.ipk.bin」をダウンロード

ruby-termios 0.9.4
「ruby-termios_0.9.4-2_arm.ipk.bin」をダウンロード

ライブラリの紹介等

Hpricotは、HTMLを解析してオブジェクトを生成します。HTMLから特定の部分を切り出したい場合等に便利。正規表現を使わず思ったものを切り出せます。

WWW::Mechanizeは、あたかもブラウザを操作するかのようにRubyからWebアクセスできます。普通はRubyからWebをいろいろいじろうとすると、HTMLの中身を仔細に調査する必要がありますが、WWW::Mechanizeを使うと、かなり見た感じでいけます。Cookieやヒストリなんかも管理してくれます。

正規表現でバリバリやるより、スクリプトのメンテナンス性が向上します。

Linux Zaurusで動かすと、ちょっと重いですが。

何の役に立つのか? サンプル

WWW::MechanizeとHpricotでmixiのあしあとを取得する例です(リニューアル後のさっき試しました)。
World Wide Walkerさんの「mecanize.rb で mixi diary を自動取得する」のパクりともいう。

mixiのような認証があるサイトの場合、普通はログインフォームからCookieをもらって、それをヘッダにセットしてログインしないと読めないページを読む、といった処理をしますが、WWW::Mechanizeがその辺りのCookie管理をやってくれているので楽ができてます。

取得したあしあとページから必要な部分を切り出すのをHpricotでやってます。
ほぼ正規表現無しでスクレイピングができちゃってます。便利。

あしあとの取得ならAPIを使うべきですが、とりあえずサンプルということで。

アクセスログマニアの方は、こういうのをCronInetで定期起動させて、Linux Zaurusでいろいろなログを監視してみては。

#! /usr/bin/env ruby

require 'hpricot'
require 'mechanize'
require 'logger'
username = 'YOUR_EMAIL_ADDRESS'
password = 'YOUR_PASSWORD'

agent = WWW::Mechanize.new {|a| a.log = Logger.new('access.log')}
page = agent.get('http://mixi.jp/')
form = page.forms[0]

form.fields.find {|f| f.name == 'email'}.value = username
form.fields.find {|f| f.name == 'password'}.value = password
form.fields.find {|f| f.name == 'next_url'}.value = '/home.pl'
page = agent.submit(form, form.buttons.first)

if /url=([^"])"/ =~ page.body
link = 'http://mixi.jp' + $1.to_s
agent.get(link)
end

doc = Hpricot(agent.get('http://mixi.jp/show_log.pl').body)
doc.search("#log_color").search("li").each do |li|
puts li.inner_text
end

徒然に

なぜか、かの伊藤栄一郎氏のサイトhttp://oohito.com/からリンクされていてビビった!

« September 2007 | Main | November 2007 »

blogparts

  • Last.fm
  • twitter

Recent Comments

無料ブログはココログ