2010-12-29

GreasemonkeyスクリプトをChromeに対応させる

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
図書館サイトを便利にするGreasemonkeyスクリプトである図書ぶらはFirefoxでしか動かなかったのですが、Chromeでも動くようにしてみました。

今回、Chromeで動かすためにやったことは以下のことです。

(1)jQueryの読み込み方法の変更
chromeで動くGresemonkeyスクリプトでjQueryを利用するを見てください。

(2)クロスドメインでXMLHttpRequestを利用できるようにする
Access-Control-Allow-Originをどこで出力すればよいのか迷ってみたを見てください。

(3)GM_*のラッパー関数を作成
図書ぶらでは、以下のGreasemonkeyで拡張されている関数を利用しています。
GM_setValue
GM_getValue
GM_xmlhttpRequest
これはchromeでは使えないので、以下のような関数を作成しました。
GM_setValue、GM_getValueは以下のような感じです。

function GM_setValue(key,value) {
 localStorage[ key ] = value;
}

function GM_getValue(key,def) {
 if( localStorage[ key ] == undefined && def != undefined ){
  GM_setValue( key , def );
 }
 return localStorage[ key ] ;
}
ここでの注意は、localStorageは文字列しか保存してくれない気配です。
GM_*のときはBooleanはBooleanで保存できていたのですが、localStorageではBooleanを文字列に変換していました。

GM_xmlhttpRequestの方は、完全互換でなくてGM_xmlhttpRequest風な以下のものを用意しました。
function GM_xmlhttpRequest(url,onload){
 var xhr=new XMLHttpRequest();
 xhr.open("get",url);
 onload&&(xhr.onload=function(){onload(this)});
 xhr.send();
}

そんなに使っていないので完全に置き換えてもよかったのですが、なんとなくこんなのを用意してみました。

とりあえずこんな感じでchromeでも動くGreasemonkeyスクリプト(chromeの場合はユーザスクリプトと言った方よいのかな)図書ぶらとなりました。

Access-Control-Allow-Originをどこで出力すればよいのか迷ってみた

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
今まで、普通のjavaスクリプトで行える通信はjavaスクリプトを読み込んだサイトに対してだけだと思っていました。

以下の図でいうとAから読み込んだHTMLに書かれているjavaスクリプトでXMLHttpRequestを利用して通信できるのはAだけでBとは通信できないという感じです。
|-----|     |-----|
|  A  |     |  B  |
|-----|     |-----|
   |           |
   |           ×
|--------|     |
|ブラウザ|-----|
|--------|

でも、どうやらXMLHttpRequest level2というのではBとも通信できるようになるらしいです。
それもjavaスクリプトの記述の仕方では特に変わったことをする必要はなくAと通信するXMLHttpRequestと同じような書き方でよいそうです。
Bと通信できるようにするには、httpのヘッダーに
Access-Control-Allow-Origin
が出力されればOKとのことです。

で、ここでこのAccess-Control-Allow-Originヘッダを出力するのは、AなのかBなのかよくわからなくなってみましたが、結論としてはBの方でした。

ちなみにGoogle App EngineでAccess-Control-Allow-Originヘッダを出力するには、以下のような感じです。
self.response.headers['Access-Control-Allow-Origin'] = '*'

*の部分は接続を許容する先を記述するところで、*と書くとどこからでもOKということになります。

すべてのブラウザで対応しているわけではなさそうですが、javaスクリプトでできることが増えそうです。

2010-12-27

chromeで動くGresemonkeyスクリプトでjQueryを利用する

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
jQueryがステキなのでGreasemonkeyスクリプトでもjQueryを利用しています。

Firefoxだけで動くGreasemonkeyスクリプトでは以下のように書いていました。
(function(d, func) {
    var check = function() {
        if (typeof unsafeWindow.jQuery == 'undefined') return false;
        func(unsafeWindow.jQuery); return true;
    }
    if (check()) return;
    var s = d.createElement('script');
    s.type = 'text/javascript';
    s.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js';
    d.getElementsByTagName('head')[0].appendChild(s);
    (function() {
        if (check()) return;
        setTimeout(arguments.callee, 100);
    })();
})(document, function($) {
    //ここに処理を書く
    alert("There are " + $('a').length + " links on this page.");
});

でもこれではChromeでは動かなかったのです。
理由はよくわかりませんが、
unsafeWindow.jQuery
がずっと
undefined
になっているせいのようです。

Chromeでも動くGreasemonkeyスクリプトでjQueryを利用するには以下のように書くとよい感じです。
function addJQuery(callback) {
  var script = document.createElement("script");
  script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
  script.addEventListener('load', function() {
    var script = document.createElement("script");
    script.textContent = "(" + callback.toString() + ")();";
    document.body.appendChild(script);
  }, false);
  document.body.appendChild(script);
}

function main() {
  //ここに処理を書く
  alert("There are " + $('a').length + " links on this page.");
}

addJQuery(main);

こちらは動きました。もちろんFirefoxでも動きます。
最初のFirefoxでしか動かない版だと、すでにjQueryが読み込まれていればjQueryの読み込み処理を行わないっぽいのでよい感じなのですが、FirefoxでもChromeでも動くというのを重視することにしてみました。


Railsでグローバルな定数を書くところ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Railsでグローバルな定数を定義する場所を検索したら、
config/environment.rb
に定義すればよいよ。みたいなことが見つかるのですが、
config/environment.rb
には、なんとなく必要となるライブラリとかをRailsのアプリケーションを動作させる
ための環境設定を記述するのがメインでなんとなくしっくりこないなぁとか思っていたところ、
config/initializers/constants.rb
というファイルを作って、これに定義するのもよいというのを見つけたので、こちらで利用することにしてみました。
定数だけを記述しているというのがなんとなく役割がはっきりしていて気に入りました。

config/initializers/constants.rb
にはモデルでもコントローラーでも利用することがある定数を定義することにしてみました。
コントローラーだけで利用するならば、
ApplicationController
に定義して、
モデルだけで利用するならば、定数を定義したモデルclassを用意して、それを継承するのがいいのかなぁとか思ってみました。

2010-12-24

Windows 7では管理者権限を持つユーザを2つ作っておくのがよい感じ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Windows 7を利用してログインしようとしたら

「User Profile Serviceサービスによるログオン処理に失敗しました。ユーザープロファイルを読み込めません」

と言われてログインできなくなりました。
過去にも一度、同じようなことになったことがあります。

これを直すには、
http://ameblo.jp/bomber1129/entry-10687686009.html

にあるように管理者権限がある別のユーザでログインして
システムの復元
をすれば再度ログインできるようになります。

管理者権限を持つユーザがひとつしかない場合、この情報を検索することもできません。
本当に急にログインできなくなるので、もしもに備えてWindows 7では、管理者権限を持つユーザを2つ用意しておいて、仮に管理者権限のユーザでログインできなくなってもなんとかなる状態にしておいた方がよい感じです。

2010-12-16

可変長プレフィックで重複が発生しないようにチェックするためのSQL

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
題名がよくわからない感じになってしまいましたが、内容としては以下のような感じです。

あるコード体系が
XXXXYYYY
のようになっていて、XXXXが親コードをあらわしてYYYYがその枝番を表しているようなコードがあり、さらにXXXX部分が固定長でないという既存コードをそのまま使いたいというケースです。
例えば、
親コードが
101
2001
とかになっていて
枝番も付与すると
10100001
20010001
みたい担っているコードです。
このような親コード部分をプレフィックスと今回、呼ばせてもらったのですが、このプレフィックス部分は、上記の例の場合
200(この枝番に2001が含まれる可能性があるため)---ケース1

1011(101の枝番とかぶる可能性があるため)---ケース2
も登録したくありません。

これをチェックする方法です。
MySQLのテーブルにプレフィックスが登録していあるとします。
テーブル名:pre
code
101
2001

まずは、ケース1をチェックします。
こちらは簡単。
select * from pre where code like '200%'
これで1件でも引っかかれば登録できないものとします。

ケース2の場合は以下のような感じです。
select * from pre where '1011' like concat(code,'%')
これで1件でも引っかかれば登録できないものとします。
こちらはデータ件数が多くなると遅くなるような気がするので注意が必要かもです。

上記2つをorで結合して以下のような感じで一気にやるのがよいかもしれないです。
select * from pre where code like '1011%' or '1011' like concat(code,'%')

2010-12-08

土偶の本

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
土偶ってすごく生命力あふれる感じがとてもステキなのです。

そんな土偶をいっぱい見ることができる本なのでオススメです。







個人的な好みとしては、縄文のビーナスと言われるいる土偶やみみずく型土偶とかが特にお気に入りです。
縄文後期の遮光器土偶や埴輪とかの中空のものもステキなのですが、なんとなくワイルド感というか力強さが若干ものたりないと思ったりしているのです。

2010-11-30

ActiveScaffoldでNestedを使ったらエラーが出たよ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
RailsのScaffoldをステキにする
ActiveScaffold
を使っています。

ActiveScaffoldは、以下のページで記載されているようにすることで管理画面をネストすることができます。
https://github.com/activescaffold/active_scaffold/wiki/API%3A-Nested

でもRails2.3で利用すると以下のようなエラーが出て利用できませんでした。
ActionView::TemplateError (undefined method `render_component' for #<ActionView::Base:0xb76b7224>) on line #39 of vendor/plugins/active_scaffold/frontends/default/views/_nested.html.erb:

調べたところ、render_componentというのが2.3では利用できないようで以下のように別途pluginを追加する必要があるようです。
script/plugin install git://github.com/ewildgoose/render_component.git -r rails-2.3

と以下のページに書いてありました。
http://code.google.com/p/activescaffold/issues/detail?id=685

これで無事にネストを利用することができるようになりました。
ステキなActiveScaffoldです。

2010-11-23

ubuntuをEee PC 1018Pに入れてみた

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
Eee PC 1018Pを持っているのですが、ハードディスクが相当あるのでいろいろマルチブートにして遊んでみようと思ったのです。

とりあえず190Gぐらいの何も使っていない領域を開放しました。

まずはお手軽にubuntuをいてみようと思ったのですが、思った以上に苦戦してしまいました。

CD-ROMなどはもう手元にないので、USBメモリを利用してインストールしようと思ったのですが、いろんなやり方を試しても
busy box
と表示されてしまいます。
このように表示した場合の対処もいろいろ検索できるのですが、どれもうまくいかず。

確証はないのですが、どうも途中でCDROMがないのに探しにいっている感じで、USBメモリを見失っているような感じです。

最終的には、コチラ
http://ubuntu10144.blog111.fc2.com/blog-entry-15.html
に書いてある方法を参考にAlternate版というものをダウンロードして
こちらを利用してLANに接続した状態で、インストーラーからネット経由で各種ファイルを取得する形でインストールを行うことでなんとか動くようになりました。

ちなみにAlternate版はコチラから取得しました。
http://ftp.riken.jp/Linux/ubuntu-iso/CDs//10.10/

とりあえずインストールが完了して、最初に動かすと無線LANも認識してくれたので、このドライバをネットからダウンロードできたらLAN接続は解除して利用しています。

2010-11-17

rubyを1.8.7から1.9.1にしてみたときのメモ

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク
rubyが1.8.7で
railsが2.3.5でアプリを作ったアプリをRails3も出ているこのご時勢なので
ちょっとアップデートを試みました。

Rilas3にするのは大変そうな気がしたので、
まずは、railsを2.3.5から2.3.10にアップデート。
こちらはそんなに困らずにアップデートできました。

そしてrubyを1.8.7から1.9.1にアップデートするために
rvmをインストールして複数のバージョンを利用できるようにしました。

rubyを1.9.1にアップデートするには、以下の対応を行いました。
(1)日本語対応させるためのマジックコメント追加
テストを行うと
invalid multibyte char (US-ASCII)
みたいなエラーが出てテストができない状況だったので、
とりあえず各ファイルに以下のようなマジックコメントを追加しました。
# -*- encoding: UTF-8 -*-


(2)FasterCSVの利用をCSVに変更
CSVの処理を行う部分があり、FasterCSVを利用していたのですが
1.9にはFasterCSVが普通にCSVとして組み込まれているようなので
FasterCSVの部分をCSVに置き換えました。


(3)mysqlの接続アダプターの変更
テストを行うと
incompatible character encodings: ASCII-8BIT and UTF-8
みたいなのがたくさん出てきました。
マジックコメントを入れたので日本語対応が済んでいると思ったのですが、
ActiveRecordの結果がいまいちな感じでした。

実際調べてみまたところ、アクティブレコードの出力が確かにASCII-8BITになっていました。
#ファイルで適用されているエンコーディングを出力
p __ENCODING__
Encoding:UTF-8
#アクティブレコードで取得したレコードのエンコーディングを出力
p n[:aaa].encoding
Encoding:ASCII-8BIT
#念のためソースに記載した日本語のエンコーディングを確認
p "あああ".encoding
Encoding:UTF-8

ruby 1.8.7では
gem install mysql
としてmysql用のアダプターを入れていたのですが、どうもこれはだめなようで
ruby-mysql

mysql2
を使う必要があるようです。

単純に移行するならば
ruby-mysql
の方がちゃんと互換性があるようです。
使うときは、以下のように既存を削除して追加する必要があります。
gem uninstall mysql
gem install ruby-mysql

mysql2の方が速いらしいし、Rails3ではこれをつかうっぽいので、
こっちを使ってみることにしてみました。
使うときは、以下のように既存を削除して追加する必要があります。
gem uninstall mysql
gem install mysql2

そしてconfig/database.ymlのadapterを
adapter: mysql2
とする必要があります。

ちなみにnum_rowsを使って検索件数を取得していたのですが、
mysql2にはないのでcountに置き換えました。

だいたいこんな感じで1.9.1の対応ができました。

ちなみに1.9にするとスピードもあがるとのことなので1.8.7のときと1.9.1のときの同じテストを行ったときの時間を参考までに。

1.8.7 Finished in 270.402445 seconds
1.9.1 Finished in 218.353968929 seconds

確かに速くなっています。