たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。
以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
Second Search更新した。Firefox 3(Beta3)とThunderbird 2に対応。
Thunderbird対応にあたって、全体的にコードに手を入れた。Firefoxだけでしか使わない部分とThunderbirdでしか使わない部分と両方で使う部分の3つにファイルを分割している。似たような構造の物に対してはこれで比較的楽に対応できるようになったんじゃないかと思う。
Firefox 3については、Placesへの対応がメイン。キーワードを設定されたブックマークを検索エンジンと同等に扱うという機能がSecond Searchにはあるんだけど、僕以外にどれだけの人が使ってるんだろう。
あと、「他の検索エンジン」サブメニューのあたりのコードもだいぶ書き直した。この辺はほんとは特に触る予定はなかったんだけど、Organize Search Enginesとの競合の解消も兼ねて、なるべく汎用的になるように変更している。っていうかテストしててなーんかうまく動かないなーと思って不思議だったんだけど、よく調べてみたらOSEの側にSecond Search用のハックが入っててそれが干渉していた。僕のアドオンのためにわざわざハック用のコードを書いてくれるなんて……よくあんなスパゲッティもスパゲッティなコードを解読してくれたもんだなぁ……と嬉しく思ったりもしたけど、このままだとせっかく修正したのがきちんと動いてくれないので、動くようにするパッチを作者の人に送りつけてみたり。
NSISは調べてみると結構色んな事ができそうではあるんだけど、日本語で解説された資料ってのが全然見つからないし、機能の詳しい使い方の説明も不足してたりして、マジ困る。仕方ないからFirefoxのインストーラで実際に使われてる物のソースを見たりなんかして。
いや、ロジックを丸パクリしたかったんじゃなくて、もっとささやかな話で、MUI(Modern User Interface、インストーラのウィザード形式の画面を提供するライブラリ)でMUI_PAGE_CUSTOMFUNCTION_PREを使って特定のページを条件次第でスキップするにあたって、ヘルプには「そういうこともできる」としか書かれてなくて実際のやり方が載ってなかったから、それを調べたかったんですよ。
Railsの案件で、Rails自体の詳細な挙動が分からなくて困ってた時も結局須藤さんには「Railsのソースを読め」と言われてしまったし。ドキュメントが不足してて困るって話と、ソースが読めれば資料になるからオープンソース万歳!って話と、そんなだからドキュメントを敢えて作る気にならなくてドキュメント不足が余計に加速されちゃうんだよって話と、色々混ざっててスッキリしない。
ちなみに調査結果としては、MUI_PAGE_CUSTOMFUNCTION_PREで指定したコールバック関数でAbortすればそのページはスキップされるようになる、ということだった。
nsIMsgDBHdrとnsIMsgFolderからメールの本文を文字列として取得する方法をあれこれ試してみてこんな感じのところに辿り着きましたとさ。
あのBug 322367「Bring back the Firefox Plush Toy(Firefoxぬいぐるみ復活希望)」が、ついにFIXEDになりました!!! コメントによると、北米専用ショップではすでに購入可能で、海外発送可能なインターナショナルショップの方でもじきに注文できるようになるんだそーです。
イギリスから個人輸入したり、哀さんに協力してもらって共同購入したりと色々ありましたが、これで誰でも気軽に手に入れられるようになる……のかな?
mozIStorageConnectionのcreateFunctionメソッドを使うとユーザ定義関数を作れるそうなんだけど、Firefox 2だとユーザ定義関数から値を返せない(返り値が常にNULLになる)。値を返せるようになるのはFirefox 3からだそうな。
const DirectoryService = Components
.classes['@mozilla.org/file/directory_service;1']
.getService(Components.interfaces.nsIProperties);
var file = DirectoryService.get('ProfD', Components.interfaces.nsIFile);
file.append('mydatabase.sqlite');
var storageService = Components
.classes['@mozilla.org/storage/service;1']
.getService(Components.interfaces.mozIStorageService);
var dbcon = storageService.openDatabase(file);
// mozIStorageFunctionインターフェースを備えたオブジェクト
var func = {
onFunctionCall : function(aArgs) {
// 渡ってくるのはmozIStorageValueArrayのオブジェクト
var data = aArgs.getString(0);
var pattern = aArgs.getString(1);
return data.match(new RegExp(pattern)) ? true : false ;
}
};
// 引数の個数を「-1」にすると可変長引数の関数になる
dbcon.createFunction('match', -1, func);
var extracted = [];
var statement = dbcon.createStatement(
'SELECT * FROM mytable WHERE match(data_column, ?1)'
);
statement.bindStringParameter(0, '^foobar');
try {
while (statement.executeStep())
{
extracted.push(statement.getString(0));
}
}
catch(e) {
}
statement.reset();
alert(extracted.length); // 0
こんなの何に使えばいいんだ?
まあどうせPlacesはFirefox 3からだし、正規表現でのマッチングをやる必要が出てくるのはそれからだと思うんだけど。でもこのコードのようにJavaScript製ユーザ定義関数でマッチングするんだったら、結局は全ての行に対して処理が行われるわけで、それだったら先に全ての行を取り出してからループ回してマッチングするのと、処理速度的には全然変わらないよね……ほんと無意味。標準の関数で正規表現が使えればいいのになあ。
検索を開始したタイミングでヘッダ情報を一気に収集するという現状の仕様だと、フォルダ内に数千件とかメールが溜まってる人はまず間違いなく死亡するので、フォルダの内容を表示したタイミングでバックグラウンドでちまちまとヘッダ情報を収集するようにして、ついでに、その収集結果をMozStorageで保存するようにしてみてるんだけど。
今の所、一つのフォルダにつき一つのレコードとして、「Subjectだけ集めたもの」「Toだけ集めたもの」のような文字列をそれぞれフィールドに保存してるんだけど、これもあんまりでっかくなりすぎるとまずいですよねえ多分。仮にSubjectが10文字のメールが1000件あったとすると、20~40KBとかそれくらいになるのかな? 3000件もあれば100KBはいってもおかしくない。これって大丈夫なんだろうか。
えーと。SQLiteの制限事項によると、SQLiteデフォルトでの文字列の最大長は1ビリオン(1000000000)バイト……えーと、だいたい1GBくらい? Firefoxのソースツリーを検索してもSQLITE_MAX_LENGTHという文字列は登場しないようなので(というのは全然根拠にならんのだけど)、このデフォルト値のまんまなんだとしたら、パフォーマンスはさておきとりあえずこのままでも動くことは動くのかな?
というか別にSQLite使う必要は必ずしもないんですけどね。なんとなく最近無駄に多用する癖が……
Hello, thank you for your mail.
The only problem now is the new version, the old one for Firefox 1.5 is a lot better and right now I prefer having Firefox 1.5 with your old extension instead of using the new one.
Have you thought of making the same as for 1.5? If not, will you do it?
Currently I have no plan to develop an extension same as TBE on Fx 1.5. I suffered from too many bugs which are from options I didn't use, so, I decided to keep developing "TBE3" only on features I really need.
Because I was a student and I had a lot of off-time, I could develop huge software like old TBE. But now I'm one of working people. There is less time and motivation.
Now there are nice projects, Tab Mix Plus and Tab Kit, suites of tabbed browsing features. And, userChrome.js is also available to make people's small requirements reality. Lots of people develop user-scripts for the extension on MozillaZine forum. I hope communities of those extensions help you.
regards,
ということで、アップデートしました。余りに久しぶりの更新すぎて更新の手順を忘れてしまっていたのはここだけの秘密です。
やってることとしては、リンク先にも書いてるけど、まず検索対象のフォルダのメール全部を走査してヘッダ情報を収集。次に、それを文字列として連結して検索用のデータを作成。それに対してXUL/Migemoで生成した正規表現でマッチングを行い、ヒットした箇所を抜き出して、それを検索語句としてThunderbirdに渡す。という手順で、ローマ字入力でのメール検索を実現しています。今のところヘッダ情報しか収集していないので、本文内に含まれる単語は検索できません。要約とかをきちんとキャッシュするようにすればできるのかもしれないけど、そこまでやると大変そうなので今のところはここまで。
ハードディスクが逝ってしまった後に再構築した環境でテストしている都合上、大量のメールがある状況でどのくらい重くなるのかは未検証です。ヤバいくらい遅くなる場合は、設定ダイアログから「メールの検索でXUL/Migemoを使用する」のチェックを無効にしてください。
んぁ。意図したわけではなかったんだけど肉の日リリースになった……
XUL/Migemoでメールの検索をできるようにしてみたいな、と思って試してみた。
メールの検索はOR検索はできるようなので、キャラクタクラスやグルーピングを展開して単語のリストを生成してOR検索したらいけるかな?と思ってやってみたんだけど、ローマ字入力から単語のリストを作る所までで数百ミリ秒くらいの遅延というのはまあ許したとしても、そこから先の実際に検索にぶち込む所で重すぎてThunderbirdが落ちた。そりゃ9000ワードをOR検索とか、いくらC++で書かれた処理が速いといっても限度があるわ。
というわけで正攻法は無理なので別のやり方を考えないといかんですね。やっぱアレかな、検索対象のメールすべてのヘッダを一旦文字列に取り出してそこに検索をかけてから、ヒット箇所の単語を実際の検索に投げるという、いかにもXUL/Migemoらしい(plus7さんよくこんなやり方を思いついたもんだ)やり方で行くしかないのかな。
どーでもいいけどこの正規表現を単語のリストに変換する処理、自分で書いておきながら、どういう理屈で動いているのかさっぱり分からんです。
追記。前述したヘッダを一旦文字列に取り出して云々のやり方を実装してみたら、数十件程度ならわりとストレスなく動くようになった。1フォルダに数百件、数千件とかのメールが溜まってる環境だとやばいかもだけど。
Firefoxの環境はデスクトップ百景を参照。
新マシンへの移行と同時にThunderbirdの本格的な利用を開始して、さっそく不満タラタラになったのでアドオンを漁ってみた。
スレッド表示してる時にソートできなくなる件について、あまりにあんまりだと思ってアドオンを作り初めてからふと「Thunderbird スレッド ソート」で検索してみたら、about:configでmailnews.thread_pane_column_unthreadsをfalseにすればよいと書かれた記事を発見した。こんなのデフォルトでfalseにしといてくれよ……
スレッドペインのコンテキストメニューで一番上の項目が「返信」じゃなくて「新しいウィンドウで開く」になってるせいで、無駄にウィンドウを開いてしまってイライラ。なのでuserChrome.cssで項目を消した。ついでにDOM Inspectorのインデントも減らしてみた。スレッド表示のネストが深くなったときに見にくくなるので、スレッドペインのインデントも変えるようにした。
#threadPaneContext-openNewWindow,
#threadPaneContext-sep-open {
display: none !important;
}
@-moz-document url(chrome://inspector/content/viewers/dom/dom.xul),
url-prefix(chrome://messenger/content/) {
treechildren::-moz-tree-indentation {
width: 9px !important;
}
treechildren::-moz-tree-twisty {
padding-right: 0px !important;
}
treechildren::-moz-tree-cell-text(colNodeName) {
margin-left: 1px !important;
}
}