Friday, July 24, 2009

a bookmarklet which loaded external script and open in another window


I updated the bookmarklet for FeedKraft. Changes are:
* Now it work even alternate links have relative path (URI).
* Open feedkraft in another window.

To keep maintainability, I decided to split complex part of the scripts into a external js file. However, Safari 4 seems to just ignore window.open() in a external loaded script, and Firefox 3.5 asks users whether popup a window or not.

To get those features work for Safari and Firefox, I struggled with javascript, but I got it.

FeedKraftbookmarklet を更新して
* alternate link の href が相対パス(URL) でも登録できるように
* 別 window で開くように
しました。

"/feed/atom.xml" のようなパスをURLに変換するコードはそれなりに長くなるので bookmarklet の javascript: 以下に続けて書くメンテしずらいので、外部 js ファイルをロードするようにしました。
しかし、外部 js ファイルからでは 別 window で開くための window.open() を実行しても Safari 4 では何も起きないし、 Firefox 3.5 では ポップアップブロックの確認が生じてしまいます。

試行錯誤の末、以下のようなコードになりました(見やすいように空白や改行を入れてます)。



javascript:
void(w = window.open());
void(e = document.createElement('script'));
void(e.src = 'http://feedkraft.com/bookmarklet.js');
void(e.addEventListener('load', function(){ w.location = FeedKraft.bookmarkURL()}, false));
void(document.body.appendChild(e));



Why does window.open() first is to avoid calling it in load event handler which behave like external file (I mean can't open a window). Annoying void() is for Firefox. Without enclosing a sentence with void(), the script will return with result of the sentence.

I'm not a Javascript ninja. I never think that this is the best solution. Please give me advice if you have idea.

load イベントで直接 window.open() すると外部 js ファイルで実行したときと同じ挙動になってしまうため、あらかじめ window を開いてから location を変更してます。
理屈わかってませんが、 void() で囲っていない文があると Firefox ではそこでストップして、その文の結果が表示されてしまいます。

Javascript は苦手なのでもっと良い方法があったら教えて下さい。

Friday, July 17, 2009

FeedKraft prototype version


I just announce that my new application service, FeedKraft, is available. As you notice from the name, it deals RSS and Atom feeds. I said it deals feeds, but for now, there is one function, feed filtering.

As for the filter function, we know there are many other filter services out there. I think FeedKraft is easier to use than Yahoo! Pipes, and little bit more powerful than FeedRinse.

The source code, implemented in Ruby on Rails, is also available here on GitHub.

Anyway, give it a try.


FeedKraft という RSS や Atom フィードを扱うサービスを公開しました。
が、今のところは外部のフィードにフィルターをかける機能しかありません。

フィードのフィルターに関しては、同様の機能を提供するサービスはいくつかありますが、Yahoo Pipe より簡単で、 FeedRinse よりちょっと強力かと思います。

特徴としては、
* 入力フィードを解析してファイルター可能な候補を選択できる (例: このブログの Atom フィードをカテゴリ Rails でフィルター)
* 作成したフィルターは公開され、他のユーザーが作成したフィルターも利用できる
* フィルター結果の feed はログイン状態での購読(subscribe)により生成されるURLにより参照する必要があるので、何人購読しているか分かる

どんだけ意味があるかわかりませんが、フィルター結果などのフィードが公開されることで、フィード提供側と利用側によるコミュニティ的な要素が広がるといいかなと思ったりもしてます。

ちなみに、Rails で実装してます。ソースも GitHub にありますので興味があったらどうぞ。

Thursday, July 16, 2009

A meta data table structure Force.com is using

InfoQ に salesforce.com の Chief Software Architect, Craig Weissman が Force.com の内部設計を語るプレゼンテーション InfoQ: The Internal Design of Force.com’s Multi-Tenant Architecture が上がってました。

こういう巨大なサービスの内部構造には興味があるので見てみました(英語をほとんど聴き取れませんでしたが)。Force.com - Multitenant Architecture Under the Covers « Blog - Dayspring Web Design and Development にも第三者による要約があります。

全体の指針として、
* 1つのバージョンだけで顧客毎のカスタマイズはしない
* 開発者は現在のバージョンと次のバージョンだけの保守で済む
* ソーシャル系サービスと違い、会社などの組織単位でリレーションを分離できるので、 OrgID のハッシュでテーブルを partition

とくに興味があったのはユーザー定義のメタデータをどうやって保持しているかで、
* オーバーヘッドが大きいので DDLを使わない(動的に CREATE/ALTER/DROP TABLE しない)
* 自由度の高いピボットテーブル? でメタデータを定義、保持
* 数値や日付などのデータも文字列カラムで保持

具体的には、プレゼンテーションの 15:00 前後のスライドで解説していますが、Fields, Objects, Data の3つのテーブルを使っています。

ちゃんと理解してるか自信ないんですけど、たとえば、

Person:
Name: Hiroshi Saito
BirthDate: 1973-09-17

という構造をつくる場合、


Objeject:
ObjID: 1
ObjName: Person

Field:
FieldID: 1
ObjID: 1
FieldName: Name
DataType: String
FieldNum: 0

Field:
FieldID: 1
ObjID: 1
FieldName: BirthDate
DataType: Date
FieldNum: 1

Data:
GUID: 1619c672-71d2-11de-8643-e784bb274b72
ObjID: 1
Name: ???
Value0: Hiroshi Saito
Value1: 1973-09-17


Person は ObjID=1 とわかっていれば、 Person は以下のクエリで検索できますね。

SELECT Value0 AS Name, Value1 AS BirthDate FROM Data WHERE ObjID = 1;


Index のあたりの話などは理解してませんが、 SalesForce が実際に運用しているデータ構造ならば自分で思いついたのよりまともなハズなので、次回、ユーザー定義データを保存する必要がある場合はこの方法でやってみようかと思います。

Friday, July 10, 2009

pony += attachment files + TLS

2010-07-30: My fork of pony is merged into benprew's pony - GitHub. Try it instead.
$ sudo gem install pony



I don't have any other servers, I mean real hardwares, apart from the server my web applications reside. However, I need to keep backup files of database dump or something precious safe from destructions. So I decide to send backup files to a gmail account.

pony makes easy to write a script sending mails, but it can't attach files nor use TLS transport.

Using Tmail, it's easy attaching some files to a mail. And Net::SMTP, included in ruby 1.8.7 or latter, can use TLS/SSL transport without hustle (for ruby 1.8.6 or earlier, there is the smtp_tls gem). So I forked and patched pony.

I sent a pull request to the author of pony, but for now, you can use my fork:

Web アプリケーションの DB のバックアップをとりたいけど、サーバーが1台しかないのでバックアップファイルをメールに添付して gmail のアカウントに送ることにしました。

pony を使うと簡単に送信することができます。 Pony はSMTP 経由で送信もできるんですけど、今回必要なファイル添付と gmail の SMTP サーバーが要求する TLS/SSL 通信も対応してません。

ファイル添付は TMail で簡単にできるし、TLS/SSL も ruby 1.8.7 以降の Net::SMTP なら実装され、 1.8.6 以前でも smtp_tls gem をインストールすることにより利用できるので、それらに対応できるよう Pony を fork して変更してみました。

Pull リクエストを pony の作者に送ったんですが、マージしてくれるかわからないのでこれを使って下さい。



$ gem sources -a http://gems.github.com
$ sudo gem install hiroshi-pony



Here is a sample:

メールを送るスクリプトはこんな感じ




require "rubygems"
require "pony"
Pony.mail(
:to => "example@gmail.com",
:subject => "DB backup",
:via => :smtp,
:smtp => {
:host => "smtp.gmail.com",
:port => "587",
:auth => :plain,
:user => "example",
:password => "********",
:tls => true
},
:attachments => {"database_name.sql.gz" => `pg_dump database_name | gzip`}
)

Monday, June 15, 2009

annotates where partial code come from

Rails アプリケーションの view で partial を多用しているときに、どこからどこまでがどの partial でレンダリングされているのか知りたいことがあるのでプラグイン partial_annotation というものを作ってみました。


<%= render :partial => "/foo" %>


がレンダリングされるとこうなります。


<!-- begin partial "_foo.html.erb" -->
content of the partial....
<!-- end partial "_foo.html.erb" -->


ちなみに、development 以外では無効になるようにしてます

Friday, June 5, 2009

Safari hanging up due to Dropbox contextual menu plugin

最近、気がついたら、 Safari の Contextual Menu を開こうとするとしばらくハングするようになったので犯人探しをしてみました。
Dropbox にバグ報告をしようと思って英語で書いたものです。

Recently I got Safari hanging up when I try to pop up contextual menu in Safari.
So I sampled with Activity monitor.app when Safari got hang.

...
1724 TContextualMenuPlugin::LoadCMPluginsFromCFPlugin(FSRef const&, __CFArray*)
1724 DropboxPluginFactory
1724 AllocDropboxPluginType
1724 reconnect
1724 connect$NOCANCEL$UNIX2003
1724 connect$NOCANCEL$UNIX2003

I found a suspect.

~/Library/Contextual Menu Items/DropboxPlugin.plugin


After removing DropboxPlugin.plugin, Safari's contextual menu is popped up as smoothly as ever.
However, every time Dropbox.app is started, it places the plugin. As I'm a programmer I can't bear torment of removing the plugin every boot time of Mac by hand. So I renamed the plugin:

$ mv /Applications/Dropbox.app/Contents/Resources/DropboxPlugin.plugin \
/Applications/Dropbox.app/Contents/Resources/DropboxPlugin.disabled.plugin


I'v used Dropbox for most half a year. Until this problem happened, it works great. I couldn't remind when I upgraded Dropbox app recently, so I suppose other changes of mac caused this problem.

Mac OS X 10.5.7
Safari 3.2.3 (5525.28.3)
Dropbox.app 0.6.402 or 0.6.507

Monday, May 4, 2009

Rechargeable Batteries

Lifehacker の記事のリンクから、 Coding Horror: Adventures in Rechargeable Batteries を読んで、乾電池型充電池について勉強になりました。というか、おすすめの充電器が欲しくなった。

箇条書きに要約すると、

  • アンペア時(mAh) の大きさに踊らされるな、エネループ(または同等品)を買え。ニッカド(Ni-Cd)電池の10-20%、(従来の)ニッケル水素(Ni-MH)電池の20-30%の容量が一ヶ月で自己放電する。(eneloop - wikipedia によると15%/年なのでおよそ1.4%/月の自己放電)

  • 低電流で充電すると充電に時間はかかるが、電池を痛めない。高電流で急速充電すると、電池の寿命が縮まる。

  • 安い充電器(とくに急速充電タイプ)は電流や充電済みかどうかのチェックをしないので電池を痛める。(ほとんどの電池とセット売りのものはゴミ)

  • La Crosse Technology BC-900 AlphaPower battery chargerを買え。充電電流を設定できたり、現在の容量(mAh)を確認できる。


まあ、もっと奥が深いのでしょうが、そんなに深追いはしたくないので。

ちなみに、 BC-900 の安価版 BC-700 は充電電流を高く設定できないだけで他の機能は同じ、余計なケースや充電池が付いていなので、それを amazon.com で注文しようとしたら、米国内のみ出荷可能でした。

元記事にあるように米国より日本のほうが乾電池型充電池は出回っているようなのですが、日本では電池メーカーの専用充電器でないものはほとんどみあたりませんね(ミニ四駆向けの高価な特殊なやつは除外)。TECHNO CORE という会社が作っていたみたいですが、今は販売していないようですし、液晶で容量などを表示できるやつが欲しい。

ほとんど、受け売りなので間違いなどの指摘は大歓迎です。