翌朝一羽しかいなくなってた(帰りに見たらまた居たから飛ぶ練習でもしてるのかも)
2009年7月14日火曜日
2009年7月6日月曜日
ATOKの電子辞典をFirefoxで引く(Jetpack)
Jetpackで何か作ってみたかったので作ってみた。
OperaでATOK 2007 for Windowsの電子辞典を使うためのツールが必要。
ステータスバーにATOKのアイコンが出ます。
テキストを選択した状態で、アイコンをクリックすると電子辞典の検索を行います。
本当はコンテキストメニューに登録して呼び出すのがやりたかったんだけど、
Jetpackでやる方法がわからなかったので、この形にしました。
(function() {
var cmd = 'c:\\path\\to\\GetTextOperaLClick.exe';
var convert = function(s, charset) {
var ccls = "@mozilla.org/intl/scriptableunicodeconverter";
var cif = Components.interfaces.nsIScriptableUnicodeConverter;
var c = Components.classes[ccls].getService(cif);
c.charset = charset;
return c.ConvertFromUnicode(s);
}
var lookup = function(s) {
var fcls = "@mozilla.org/file/local;1";
var fif = Components.interfaces.nsILocalFile;
var pcls = "@mozilla.org/process/util;1";
var pif = Components.interfaces.nsIProcess;
var file = Components.classes[fcls].createInstance(fif);
file.initWithPath(cmd);
var process = Components.classes[pcls].createInstance(pif);
process.init(file);
var args = [convert(s, "shift_jis")];
process.run(false, args, args.length);
}
jetpack.statusBar.append({
html: '<img id="icon_img" src="http://www.atok.com/favicon.ico />',
width: 30,
onReady: function(doc) {
$('#icon_img', doc).css({
cursor: "pointer",
});
$(doc).click(function() {
var w = jetpack.tabs.focused.contentDocument.getSelection();
if (w.length) {
lookup(w);
}
});
}
});
})();
選択するだけで検索する版(使いにくい)
アイコンをクリックすると、機能のon/offができます。
無効(初期)状態では、アイコンが半透明になっています。
有効になっているときは、テキストを選択してマウスのボタンを離すと電子辞典の検索が動きます。
(クリックイベントが発生したときに、選択されているテキストの長さで判断してます)
(function() {
var cmd = 'c:\\path\\to\\GetTextOperaLClick.exe';
var enabled = false;
var convert = function(s, charset) {
var ccls = "@mozilla.org/intl/scriptableunicodeconverter";
var cif = Components.interfaces.nsIScriptableUnicodeConverter;
var c = Components.classes[ccls].getService(cif);
c.charset = charset;
return c.ConvertFromUnicode(s);
}
var lookup = function(s) {
var fcls = "@mozilla.org/file/local;1";
var fif = Components.interfaces.nsILocalFile;
var pcls = "@mozilla.org/process/util;1";
var pif = Components.interfaces.nsIProcess;
var file = Components.classes[fcls].createInstance(fif);
file.initWithPath(cmd);
var process = Components.classes[pcls].createInstance(pif);
process.init(file);
var args = [convert(s, "shift_jis")];
process.run(false, args, args.length);
}
jetpack.statusBar.append({
html: '<img id="icon_img" src="http://www.atok.com/favicon.ico />',
width: 30,
onReady: function(doc) {
$('#icon_img', doc).css({
cursor: "pointer",
opacity: 0.4
});
$(doc).click(function() {
var elem = $('#icon_img', doc);
var a;
if (enabled = !enabled) {
a = 1;
$(jetpack.tabs.focused.contentDocument).click(function() {
var w = jetpack.tabs.focused.contentDocument.getSelection();
if (w.length) {
lookup(w);
}
});
} else {
a = 0.4;
$(jetpack.tabs.focused.contentDocument).unbind('click');
}
elem.css({opacity: a});
});
}
});
})();
2009年7月1日水曜日
1passでpygmentsの出力したhtmlにスタイルを埋め込む
前のは出力されたcssとHTMLを処理するのでstyle, lexerなんかは好きにすればよかったけど、
今回は1passなのでそこら辺の指定をできるようにしてみた。
from pygments import highlight from pygments.lexers import get_lexer_by_name, get_lexer_for_filename from pygments.formatters import get_formatter_by_name from xml.etree.ElementTree import ElementTree, XML import cssutils from cssutils.css import CSSRule from sys import stdout from optparse import OptionParser def write(filename, style_name='colorful', formatter_name='html', lexer_name=None, out=stdout): fmtter = get_formatter_by_name(formatter_name, style=style_name) if lexer_name: lexer = get_lexer_by_name(lexer_name) else: lexer = get_lexer_for_filename(filename) css = cssutils.parseString(fmtter.get_style_defs()) rules = dict([(x.selectorText, x.style.cssText.replace('\n', '')) for x in css.cssRules if x.type == CSSRule.STYLE_RULE]) tree = ElementTree(XML(highlight(open(filename).read(), lexer, fmtter))) for elem in tree.getiterator(): c = elem.get('class', None) if c: style = rules.get('.'+c, None) if style: elem.attrib['style'] = style tree.write(out) if __name__ == '__main__': optparser = OptionParser(usage=u'usage: %prog [options] file') optparser.add_option('-S', '--style', dest='style', help='style', default='colorful') optparser.add_option('-f', '--formatter', dest='formatter', help='formatter', default='html') optparser.add_option('-L', '--lexer', dest='lexer', help='lexer') options, args = optparser.parse_args() if len(args) == 1: write(args[0], options.style, options.formatter, options.lexer, stdout) else: print '** no input file specified **' optparser.print_help()
2009年6月29日月曜日
ハードディスク買った
外部電源の外付けハードディスクだと、つなぐのが面倒でバックアップをサボりがちだったので、
バスパワーで動くUSB接続のハードディスクをさがしていた。
ちょうど、来月分の生協のチラシにHDPS-U500がのっていたので、これでいいかな?と思っていたら、
土曜日に寄った川崎のヨドバシで同じものがポイント20%還元になってた(ポイント分引けば9000円切ってる)ので買ってしまった。
8G/残りでパーティションを分けて、8Gの方からTrueImage(Home 10)を起動できるようにした。
手順は簡単で、TrueImage が起動する USB-HDD ( USB メモリ ) の作り方をそのままやればできた。
基本的にWindows上でバックアップするけど、復旧のこと考えるとこうしておいた方が安心。
(私の環境は1スピンドルでUSBが3ポート。USB光学ドライブはUSBを2ポートふさいでしまうので、HDDをつなぐと全部埋まる)
2009年6月4日木曜日
pygmentsの出力したhtmlにスタイルを埋め込む
ここでソース張っても色とかつけるのが大変なので、pygmentsのhtml出力とcssを結合するスクリプトを書いてみた。
embedstyle.py
import sys
from xml.etree.ElementTree import ElementTree
import cssutils
from cssutils.css import CSSRule
css = cssutils.parseFile(sys.argv[2])
rules = dict([(x.selectorText, x.style.cssText.replace('\n', '')) for x in css.cssRules if x.type == CSSRule.STYLE_RULE])
tree = ElementTree(file=open(sys.argv[1]))
for elem in tree.getiterator():
c = elem.get('class', None)
if c:
style = rules.get('.'+c, None)
if style:
elem.attrib['style'] = style
tree.write(sys.stdout)
使用例
スタイル生成→HTML出力→結合
pygmentize -f html -S colorful > test.css
pygmentize -o embedstyle.html embedstyle.py
python embedstyle.py pkglist.html test.css > out.html
これで出力したのがこのページのコード
ubuntu/debianのインストール済みパッケージリストを整形して出力する
ディスクの空きがちょっと減ってきたので、サイズが大きいパッケージを知りたくて作ってみた。
python-aptとprettytable使ってます。
#!/usr/bin/python
import apt
from prettytable import PrettyTable
pt = PrettyTable(["package", "version", "size"])
pt.set_field_align("package", "l")
pt.set_field_align("version", "r")
pt.set_field_align("size", "r")
pt.set_padding_width(1)
SizeToStr = apt.SizeToStr
for v in sorted([x.installed for x in apt.cache.Cache() if x.isInstalled], key=lambda v: v.installed_size):
pt.add_row((v.package.name, v.version, SizeToStr(v.installed_size)))
print pt
出力
+----------------------------------------------------------+------------------------------------------+-------+
| package | version | size |
+----------------------------------------------------------+------------------------------------------+-------+
| adobe-certs | 1.0.8210 | 0 |
| adobeair1.0 | 1.5.1.8210 | 0 |
| tweetdeckfast.f9107117265db7542c1a806c8db837742ce14c21.1 | 0.22 | 0 |
| gnuplot | 4.2.5-2 | 20.5k |
| uim | 1:1.5.3-1 | 20.5k |
(省略)
| texlive-latex-extra-doc | 2007.dfsg.17-2ubuntu1 | 110M |
| openoffice.org-core | 1:3.1.0-3ubuntu2 | 113M |
| llvm-dev | 2.5+svn20090504-0ubuntu1 | 117M |
| ghc6 | 6.10.3-2ubuntu1 | 148M |
+----------------------------------------------------------+------------------------------------------+-------+
2009年6月3日水曜日
print >>sys.stderrによる出力をloggingで出したい
sys.stderrにメッセージを出力しているモジュールがあって、それを書き換えずに何とかしたいので考えてみた。
とりあえずうまくいったけど、いいのかわからない。
(追記
すっかり忘れてたけど、sys.stderrをほかの変数で参照してたらだめだった。当たり前なんだけど…
別モジュールで、from sys import stderr
なら
モジュール名.stderrを書き換えればOK)
import sys
import logging
from StringIO import StringIO
class redir(object):
def __init__(self, f):
self.f = f
self.eol = True
def write(self, buf):
if buf == '\n':
if self.eol:
self.f('')
else:
self.eol = True
else:
self.eol = False
self.f(buf)
print >>sys.stderr, "hoge"
logging.basicConfig(filename='hoge.log', level=logging.DEBUG)
sys.stderr = redir(logging.error)
print >>sys.stderr, "hoge1"
print >>sys.stderr
print >>sys.stderr, "hoge2"
これで、最初の出力(hoge)はstderrに、以降の出力(hoge1,改行のみ,hoge2)はhoge.logに出力される。
調べ方メモ
6.6. The print statementを見て、出力先のオブジェクトにwriteが必要なことと、(必要なときは)最後に'\n'がくることはわかった。
writeに渡されるバッファに最後の改行が含まれているのか、改行だけ別に呼ばれるのか気になるので調べてみた。
適当な関数を作って、disで調べた。
>>> import dis
>>> def f():
... print >>None, None,
...
>>> def fln():
... print >>None, None
...
>>> def fnl():
... print >>None
...
>>> dis.dis(f)
2 0 LOAD_CONST 0 (None)
3 DUP_TOP
4 LOAD_CONST 0 (None)
7 ROT_TWO
8 PRINT_ITEM_TO
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> dis.dis(fln)
2 0 LOAD_CONST 0 (None)
3 DUP_TOP
4 LOAD_CONST 0 (None)
7 ROT_TWO
8 PRINT_ITEM_TO
9 PRINT_NEWLINE_TO
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> dis(fnl)
2 0 LOAD_CONST 0 (None)
3 PRINT_NEWLINE_TO
4 LOAD_CONST 0 (None)
7 RETURN_VALUE
>>>
たぶん、PRINT_ITEM_TOがデータの出力で、PRINT_NEWLINE_TOは改行であろうことはわかる。
改行付きのprintがPRINT_ITEM_TOと、PRINT_NEWLINE_TOと二つに分かれているので、2回に分けてwriteが呼ばれそうなこともわかる。
ともかく、PRINT_ITEM_TOとPRINT_NEWLINE_TOは間違いなくキーワードなので調べると、PRINT_ITEM_TOとPRINT_NEWLINE_TOは拡張版print statementで使われるのがわかる。それぞれ出力を行う命令なので、writeが二度呼ばれるものとして扱ってよさそう。
素直にそのままloggingすると、最後の改行までログに残ってしまうので邪魔。ただ、単純に'\n'だけ渡されたときに無視するようにすると、改行だけのやつ(fnlみたいなやつ)は捨てられてしまうので(ログに出すことしか考えていないので、許容できる場面もあると思うけど)簡単に対応しておく。
- 前回の出力が改行じゃないときは無視(PRINT_ITEM_TO->PRINT_NEWLINE_TOで呼ばれる場合)
- それ以外は空文字列を出力
2009年3月20日金曜日
KDEが使える環境でAIRアプリをKDE外から使う
まず結論。
dbusが使える環境で、kdewalletmanagerを起動した状態で、
すればいける(環境変数の値は別のでもいいかもしれないけど調べてない)
KDE_SESSION_VERSION=4 KDE_FULL_SESSION=true /opt/TweetDeck/bin/TweetDeck
以下経緯など
私のマシンでは、kubuntuのKDE4(4.2.1)はちょっと重いので
プログラムを書くのがメインな時はawesomeを使ってみることにした。
(まあ、それでも4.1.xの時と比べたらだいぶマシになった)
そこで困ったのが、AIRアプリであるTweetDeckが動かないこと。
WindowsでもLinuxでも動いて、しかもグループ分けが便利なので気に入って使ってる。
起動すると、次のようなメッセージが出て、画面は表示されるものの使えない状態になる。
Adobe AIRはいまのところKDEとGnomeしかサポートしていないらしい。
$ /opt/TweetDeck/bin/TweetDeck
Unknown desktop manager, only Gnome and KDE are supported
.
試しに
KDEWM=/usr/bin/awesome
にして、KDEで使うWindow ManagerをawesomeしたらTweetDeckも動くけど、なんかしっくりこない。
しかたがないので、awesome単体で使える方法を調べることにした。
KDEでTweetDeckを起動するとKwalletが動くので、手動でkwalletmanagerを起動してから
TweetDeckを起動してみたが、また同じメッセージが出てだめだった。
straceを使ってKDEから起動するときと、awesome環境から起動するときの違いをみてみたら、
どうもdbusでkwalletを探してるっぽいことが分かった。
でも、kwalletmanagerを起動しておけば、ちゃんと見つけられるし、
$ qdbus org.kde.kwalletd /modules/kwalletd org.kde.KWallet.localWallet
kdewallet
awesome環境で起動するときは、そもそもkwalletを探していないようなので不足があるようだ。
何か無いかとAIRのディレクトリを探ろうかと思ったら、いきなりlibCore.soを見つけたので、
おもむろにstrings libCore.so | grep -i kde
してみたら、
KDE_SESSION_VERSION, KDE_FULL_SESSIONが出てきた。
こいつらにKDEで見た値を入れたら動いてしまった。
2009年3月12日木曜日
パクチー食ってきた
なかなか理解されることがないのですが、私はパクチーが大好きなのです。
Twitterで@macchaさんが行きたいと言ってたのに便乗させてもらう形で、
@beakmarkさん、@hidaqaさん、@macchaさん、 私の連れ、私の5人。
@beakmarkさん、@hidaqaさんは初対面なので緊張した。
経堂は通ったことはあるけど、降りたのは初めて。
上品ドライバーのせいで、道が狭くて迷いやすいイメージがずっと付いてたけど、
少なくとも駅前はそんなこと無かった。
お料理ですが、思ったより普通においしくて微妙に残念 笑
パクチーが絶対駄目という人以外は、無茶なオーダーしなければいけると思う。
辛いのが多かった気がするので、辛いのが駄目な人もちょっとつらいかも。
根っこが好きな私は、生姜の焼酎と牛蒡の焼酎をいってみました。
生姜はかなりアリで、牛蒡は微妙。
他にも珍しいドリンクがあったけど、私は非常にアルコールに弱いのでやめておいた。
真っ赤だったし…
お店の雰囲気は、ちょっと騒がしい(子供が元気に遊んでたり)けど、
楽しい感じで是非また行きたいと思いました。おいしいしね。
店長とかオーナーとかもおもしろかった。
もうじき立ち飲みが出来るスペースが出来るとか。
2009年3月6日金曜日
2009年2月26日木曜日
linux-2.6.28でのIEEE802.11a
Ubuntu 9.04のカーネルに2.6.28系が来ているので使っていたが、
2.6.28-8.21でCONFIG_WIRELESS_OLD_REGULATORY=n
になった影響か、
家で使っている802.11aのチャンネルが使えなくなった。802.11b/gは使えた。
wireless.kernel.orgのキュメントによるとそういった情報をカーネル外に出して、udev経由で設定するようになったらしい。
どこかで見たけど、分離するようにしたのは、カーネル内に入っている情報はUS, JP, EUだけしかなく、しかもカーネルモジュールのパラメータ(cfg80211だな)でしか設定できないからだったはず。
カーネルイメージの依存関係でwireless-crdaが入ってきたが、
変更方法をみると、iwはまだubuntuにパッケージが無いし、wpa_supplicantも0.66だった。
しかもwpa_supplicantを直接使ってないので、wicd(最近NetworkManagerから乗り換えた)が
COUNTRY設定に対応してくれないと多分面倒っぽい。設定ファイルに一行足すだけかも知れないけど。
結局、debianのiw(と関連パッケージ)を入れて解決した。
設定は変更方法の所に書いてあった通りやればok.
sudo iw reg set JP
これをやったあとに今まで通りscanするだけで、自宅のAPが発見できるようになった。
追記
よく分からんが、環境変数COUNTRY=JPを設定して、
/sbin/crdaを実行するだけで設定できた。
iw無しでも平気だったようだ…
前やったときは駄目だったんだけどな…
(ちなみにwireless-crda 1.6は壊れてる。レポートしようとしたらすでにレポートされてた)
2009年2月3日火曜日
gnome-terminalをgnome外で動かす
wubiでセットアップした環境ではgnome上でgnome-terminalが問題なく使えるのに、
イメージを共有しているcoLinux側では、gnomeを動かしていないからか動かなくなった。
$ gnome-terminal
Failed to contact the GConf daemon; exiting.
検索してみると、gnome起動前にgconfにアクセスできないというのを見つけた。
GConf-2.22ならいけてGConf-2.24でこの状況になるらしい。
workaroundにしたがって次のようにする。
eval `dbus-launch --sh-syntax`
gconftool-2 --spawn
上記の二つのコマンドを実行しておけば、gnome-terminalが起動できる。
上記のコマンドを実行したセッションが生きている状態ならば、他のシェルからでも、
環境変数DBUS_SESSION_BUS_ADDRESS
を設定するだけで大丈夫。