Opera 15.00 で Chrome の拡張機能をなんとなくうごかす(自己責任)

とても暫定的なてきとうな技術者的にはけっこうバッドな方法だと自覚しているので対処療法なのでやるかは自己責任。

Opera 15.00 リリース

12.15 から Opera Next だった 15 が今日リリースされました。前から言われていたとおり Chromium ベースのものです。Presto とか Carakan のそれではないです。設定項目もすごく簡略化されて、いまのところツールバーまわりいじれないですね*1UA

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.52 Safari/537.36 OPR/15.0.1147.132

とかなんとか OPR ってのがでてる。Mozzilaなのか Webkit なのか Gecko なのか Chrome なのか Safari なのかよくわからない感じになってますけど、OPR です。opera:config とかは config にリダイレクトされます。

UI まわりやなんやらが変わっているのはおいておいて、とりあえず拡張機能はそのままでは動きません。ChromeSafariOpera それぞれの拡張機能はだいたい似ている感じのはずですけど、manifest とかがちがうっぽいとかあります。12系までは HTML/CSS/JS を詰め込んだ zip ファイルにパッケージして oex という拡張子にしていたはずだけど、今回 Chromium ベースのものなので crx/nex にするっぽいです。

ちなみに 12までの oex は Converting OEX extensions to CRX/NEX - Opera 15+ extensions documentation で変換できるっぽいです。

とりあえずうごかす(保証はない)

Google Chrome でいれた拡張機能はなんとなく動くかもしれません。

  1. Chrome拡張機能の設定から「デベロッパーモード」をチェックし、IDを確認します。
  2. その ID が ~/Library/Application Support/Google/Chrome/Default/Extensions/ とか C:\Users\username\AppData\Local\Google\Chrome\User Data\Default\Extensions とからへんに実体があります。
  3. バージョンを指定してフォルダごとコピーとかして Opera拡張機能設定の「開発者」から「パッケージ化されていない拡張機能を読み込む」でフォルダを選択します
  4. とりあえずはいるようななにかがでます。警告とかきっとでます。

とりあえずいくつかいれてみましたがとりあえず動いたり動かなかったりします。

技術的な話

Welcome! - Opera 15+ extensions documentation によると .nex という拡張子にして Chromium ベースな拡張だけど Opera 用の manifest とかを用意してアップロード、ということになるんでしょうか。Opera 特有としてはスピードダイアルまわりはさわれるようです。スタッシュとディスカバーまわりはどうなるのかな。スタッシュのAPI叩けて Opera Link できたらちょっといいかもしれない。まあただそこはもう Pocket とかでやってる人のほうが多そうだけど、どうなんだろう*2

これからの Opera

どうなるんでしょうか。

個人的には Opera はプロダクトだけじゃなくて音楽パネルやコミュニティや個人的な思い入れがわりとあるのでしばらく応援したいので使うとおもう。そしてこうして15でかわってしまうことで去ってしまう人へのひっかかりがあれば、まあ、うれしいかもしれない。気持ちが去ったら Firefix(Vimperator) にするかもしれないとは前から思っているし、機能なら Chrome でいい、拡張するなら Firefox にすればいいとは前々からずっと思っていた。でも気分として Opera最強伝説(笑)が宗教なのはある。

もうひとつは、いままで UserJS 関係でお世話になった分を形にして返すというのもいいかな、とかは思ってます。揺れてますね。

追記

Opera アドオンとしてそもそも同じようなものがあるんですね……。後から知った
拡張機能「 Download Chrome Extension」 - Opera アドオン

*1:アドレスバーは下にしてURLは完全表示にしたい

*2:マウスジェスチャーにしてもスピードダイアルにしてもブラウザ側で機能をつけてしまうことの意味は少しはわかる

クロスブラウザで確認するとき、modern.IE というIEテスト環境がすごい

初めて知った。英語は知らないけど日本語版はちょうど今年4月だから、わりと最近の話みたい。
Home | Testing made easier in Internet Explorer | modern.IE
modern.IE の更新: VM の無料ダウンロード、Windows 8 QuickStart Kit、コード スキャン ツールの強化など - IEBlog 日本語 - Site Home - MSDN Blogs

クラウドォォ上でシミュレートできるとか、どうやら仮想マシン用のVMを配ったりしているらしい。Windows, Mac はもちろん Linux にも対応しているし、Virtualbox, VMWare Fusion, Parallels の3種類ともそれぞれのVMを配っている。IEのバージョンとOSのバージョンもかなり詳細においてある。ただし日本語のフォントがはいってないっぽいのでそれはあきらめるか、自前でフォントいれるか。自前でフォントいれられるかな?試してない。

IE10 もよい

実機とまではいかなくてもデバッグツールでIE10, 9, 8, 7 までは表示モードと互換表示とかそこらへんをカバーしてくれるので、それも使える。

はい

MS、やる気が出るとすごい。やる気がでないとIE6-8みたいになるけど。「Apple は iOS で Mobile Safari でブラウザの進化を止める動機がある。第二のIE6が生まれる可能性がある」というのも頷ける。ジャスコかイオン出して商店街壊滅させて便利を存分に享受させても都合が悪くなれば撤退する、みたいな話にも通じる。

外部API使用でも安心してコードをかくための、mock をつかったテスト

TwitterFacebook に限らず、外部APIを叩かなければならない場面は出てくる。ただでさえテストコードかけないと不安になるのに、外部APIの挙動にあわせてうまく連携しないといけないケースでテストコードがかけないのはかなりこわい。そういうとき、mock が使える。

Mock - Mocking and Testing Library — Mock 1.0.1 documentation
requests と mock を使ってみる - Twisted Mind
python の mock ライブラリを使ってみる: Addicted To Indentation

つかう

テストコードとかテストケースの話になるとモヒカンが飛んできそうなので*1すごくざっくりした理解で書いておく。

from mock import Mock
# モックをつくる
m = Mock()
# m を呼び出すと必ず "hogemoge" がかえってくるようにする
m.return_value = "hogemoge"
# テストする
assert m == "hogemoge"

実際テストコードの記述は unittest や Django の unittest、テストランナーとしては nose なり pytest なり Django test コマンドで走らせたりする。

もうちょっと使う

自分が実装している関数ではなく、外部ライブラリに依存している場合、それの挙動を差し替える

from mock import patch
import some_method
# context_manager で呼び出す
import mymodule
with patch("mymodule.coooooool_script") as m:
    m.return_value = "it's cool"
    self.assertEqual(some_method(), m)
# デコレータで呼び出す
class Tests(TestCase):
    @patch(return_value="it's cool")
    def coooooooool_script_vaild(self, m):
        self.assertEqual(some_method(), m)
# 例外を起こしたい
def coooooooool_script_vaild_valid(self)
    with patch("mymodule.coooooool_script") as m:
        m.side_effect = CoooolError()
        with assertRaises(CoooolError):
            some_method()
# インスタンスメソッドを書き換えたい
# なのでクラスもモックにする必要がある
import MyCoooooolClass
patch('MyCoooooolClass')
def coooooooool_script_vaild_valid_valid(self, mock_class):
    with patch("mycoooooolclass.coooooool_script") as m:
        instance = mock_class.return_value
        instance.soooomeeeeeeeethod.return_value = "hai"
        self.assertEqual(instance.soooomeeeeeeeethod, "hai")

いろいろ記述方法やつかいかた、あるいはテストコード自体に疑問がわいたりもするけど、参考資料みながらこんな感じでかいていた。もっといいやりかたがあるとうれしい。

まあ

しかし「モック便利でなんでもできるけどモック職人になったらそれはそれで考えたほうがいい」というのもあるし、テストしやすい設計だいじだなー。

*1:指摘自体は受けたいけど、前置きしておかないとちょっとこわい

mercurial で一部の変更をコミットする

ある機能やバグを修正するとき、ついでにまとめて修正してしまうとかある。そのとき、まとめて修正してしまったのは仕方ないけれどコミットとしては別にしておきたいときに使う。git で言うと add するタイミングや add -p 的なこと。

導入

.hgrc に追記

[extension]
record =

つかう

あんまり考えなくても対話的に聞いてくれるので楽

hg record

とりあえず今回はまとめてしまったものを y/n で選択してコミットを分けた。なんだか選択肢はいろいろあるけど、とりあえず y/n で選択、qで強制終了だけつかった。

まあ

かなり使い勝手が良い。ありがたい

Django のダミーデータを大量投入するスクリプトを対話環境に対応させるシェルスクリプトで自動化した

やっぱりだるかった

Django アプリのダミーデータを大量投入するスクリプトをかく - AtAsAtAmAtArAのをコピペ運用でもよかったけど、コピペ条件かわったりいちいちもうそういうのだるかったので、やっぱりデータを初期化するところまで自動化することにした。

expect をつかった

Django ORM から生成したいからスクリプトは変えたくない。でも余計な python ライブラリは気持ち的にあまりいれたくない。python manage.py sql... とかいろいろあるけど、どうもつかえなさそうだ。python manage.py shell は python -c みたいに直接実行ができない。対話シェルになるのは必然っぽい。じゃあどうしよう。

対話シェルになってしまうものをむりやりどうにかできないか探したらあっさり expect というのが見つかった。パターンマッチさせてコマンドを実行させてしまう。すごい。sshrsync とか useradd とかで使うのを想定しているみたいだけど、これはいけそうだ。

sudo apt-get install expect

参考::clmemo@aka: Expect コマンドで passwd 変更
参考::Linux なら expect でコマンドを自動化しよう | 温故知新 linux実践講座

パターンマッチは --plain でやった

python にも pexpect なるパッケージもあるけど、あんまり今回はいれたくなかったのでどうにかシェルスクリプトでやりたい。python manage.py shell だとどうしても ipython か bpython が選択されてしまう。そのとき "In [1]: "のマッチでよくわからないがコケる。こまった。

結局 python manage.py shell は --plain で ipython とか使わないプレーンな標準の対話シェルが指定できるから、それをやった。

成果

だいぶゴリ押し感ある

#!/bin/bash

current_dir = ...
target_dir = ...

cp $current_dir/make_dummy_data.py $terget_dir
rm ...
python manage.py syncdb ...
python manage.py migrate ...

expect -c "
set timeout 1

expect '>>>'
send "import make_dummy_data\n"

expect '>>>'
send "make_dummy_data.main()\n"

expect '>>>'
send "exit()\n"

interactive
"

send したら改行コードを忘れずに。エスケープはてきとう。 set timeout でタイムアウト指定できるから -1 とかにもしたけど、なんかだめっぽかったからてきとうに小さい値を入れておいた。

まあ

よかったんだが、実は echo でよかったらしい

echo "print(1)" | python manage.py shell

なにをやっていたのだか……