Chrome拡張のバックグラウンドのDOMを取得する方法
chrome.extension.getBackgroundPage().document
これでバックグラウンドページのDOMを取得できる。
またバックグランド内で定義された変数hogeも取得できる
<script> // background.html var hoge = null; </script>
<script> // NOT_backgroud.html chrome.extension.getBackgroundPage().hoge </script>
このサンプルを見て知った : http://code.google.com/chrome/extensions/samples.html#56a8d2ac24ca7bba78fd88ad57f43fc13c784497
- background.html
- contacts.html
Google Chrome 拡張機能でOAuthを利用する方法
記事について
GoogleカレンダーAPIを使って拡張機能を作りたかったけど、OAuthでの認証が必要と分かった。色々調べていると認証が通ったので、そのメモ書き。
拡張機能でOAuthを利用する際に問題になること
- CONSUMER_KEYやCONSUMER_SECRETを公開してしまうこと
- 認証の際に別URLへコールバックされること
1に関して。
Googleのカレンダーやコンタクトや何やらのGoogle Data APIを叩きたかったら、OAuthで認証する必要がある。OAuthは通常CONSUMER_KEYやCONSUMER_SECRETをサービス提供側が事前に取得する必要がある。この2つのキーは他人に公開すると悪用される場合があるため、教えてはならない。
2に関して。
OAuthの仕様上、認証に必要なキーを取得するためにコールバックで別のURLを飛ばされてしまう。コールバックのURLにはhttp://* かhttps:// しか指定できず、Chrome拡張機能を示すchrome-extension://*は指定できない。
解決策
問題1の解決策は、CONSUMER_KEYとCONSUMER_SECRETに両方'anonymous'を入れるだけ。
問題2に関して。
Chrome APIのサンプルにOAuth機能を実現するサンプルが有る。Sample - OAuth Contacts
このサンプルを実行するとユーザのコンタクト情報が取得できたことが分かる。今回はこの中の
3ファイルを利用する。これらのファイルは拡張機能でOAuthを実現するために必要なファイルである。chrome_ex_ouath.htmlはコールバック先のファイルである。内部でどういった動作をしているかはわからないので、解説はできない。
実装
以下のプログラムはGoogleカレンダーAPIを使い予定を登録するプログラムである。
まずmanifest.jsonにはこのように書く。
{ ... "background_page": "background.html", "permissions": [ "tabs", "http://www.google.com/calendar/feeds/*", "https://www.google.com/accounts/OAuthGetRequestToken", "https://www.google.com/accounts/OAuthAuthorizeToken", "https://www.google.com/accounts/OAuthGetAccessToken" ], ... }
background.htmlで認証処理を行わせる。認証の際にドメインを複数またぐので、その許可を求める。
今回はGoogleのOAuth認証を行うのでそれ用の設定をしたが、Twitterに関しては別の方が書かれていた。Loading...
background.htmlで行わせる処理。
... <script src="OAuthSimple/chrome_ex_oauth.js"></script> <script src="OAuthSimple/chrome_ex_oauthsimple.js"></script> <script> var oauth = ChromeExOAuth.initBackgroundPage({ 'request_url' : 'https://www.google.com/accounts/OAuthGetRequestToken', 'authorize_url' : 'https://www.google.com/accounts/OAuthAuthorizeToken', 'access_url' : 'https://www.google.com/accounts/OAuthGetAccessToken', 'consumer_key' : 'anonymous', 'consumer_secret' : 'anonymous', 'scope' : 'http://www.google.com/calendar/feeds/', 'app_name' : 'Application Name' }); window.chromeExOAuth.callback_page = 'OAuthSimple/chrome_ex_oauth.html'; oauth.authorize(function() { var url = "http://www.google.com/calendar/feeds/default/private/full"; var body = JSON.stringify({ "data": { "title": "Tennis with Beth", "details": "Meet for a quick lesson.", "transparency": "opaque", "status": "confirmed", "location": "Rolling Lawn Courts", "when": [ { "start": "2010-04-17T15:00:00.000Z", "end": "2010-04-17T17:00:00.000Z" } ] } }); oauth.sendSignedRequest(url, function(text, xhr) { console.log(text); }, { 'method': 'POST', 'headers': {'GData-Version': '2', 'Content-Type': 'application/json'}, 'body': body }); }); ... </script> ...
ChromeのOAuthサンプルのファイルを読み込ませる。その後に、ChromeExOAuth.initBackgroundPage APIを使い認証の設定させる。問題1の解決策で書いたようにconsumer_keyとconsumer_secretに'anonymous'を入れる。
次の行に関してだが、これはコールバックURLの変更する手続きである。コールバックURLのデフォルトは'chrome_ex_oauth.html'となっている。変更するオプションも同APIに存在するが、変更出来なかった。chrome_ex_oauth.jsの関係するコードを読むと設定方法が分かった。windos.chromeExOAuth.callback_pageに任意のコールバックURLを入れることで設定ができた。
oauth.authorizeで認証を行わせる。引数の関数はtokenが取得できた時に呼ばれる関数である。ここで初めて、GoogleカレンダーAPIを使い予定を登録したり取得することが可能となる。
最後にGoogle カレンダーAPIを使い予定を登録する。そのためのAPIはこれ。POSTメソッドを使い予定を送信する。この時JSONフォーマットで送るので
Content-Type: application/json GData-Version: 2
とした。このヘッダ情報に加えてGoogle Data APIのバージョンも追加しておいた。今回のプログラムではバージョン情報を追加しなくとも動くことが確認できた。
これらの情報を送信するAPIはoauth.sendSignedRequestである。引数はそれぞれ、APIのURL、送信後のレスポンスを受け取る関数、送信情報である。
Chrome拡張機能「ニコ生を見る予定」を作りました
この拡張について
ニコ生の放送予定をGoogleカレンダーに書く込むのがすごく面倒、そんな面倒を解決するのがこの拡張機能です。
2クリックでGoogleカレンダーの予定を作成します。
操作方法は簡単!放送予定で[Googleカレンダー]ボタンを押し、予定作成ページに移動したら[作成]ボタンを押すだけです。
Visual C++を使っていてスタックオーバーフローが起こった
原因
参考資料スタックオーバーフロー - Wikipedia
どうや大量に変数を宣言したのが原因かもしれない。
関数を呼び出しすぎて問題が起こったのではなさそうだ。なぜなら、呼び出し履歴を見ると10個ぐらいしか、関数が呼び出されていないからだ。
Binary Hacks 0x00
O'Reilly Japan - Binary Hacksを読んでみた。
動機
読もうとした同期は、低レイヤに対するコンプレックスがあるから。PythonとかPerlとか色んな高級言語を使用してきたけど、なかでどんな事が起きているのかしりたかったから。C言語を勉強し始めたのもBasicの言語を学んでいて低レイヤに対するコンプレックスから。
こういった高レイヤにある技術を知るのに低レイヤの知識はあったほうが良いので、この本を手に取ってみた。思いのほか面白い内容が書かれていた。読了後、面白いと持ったテクニック(ハック)をチェックしたら、100個中32個あった。
この32個のハックを学習する上で時間があれば、このブログにメモしておこうと思う。
2011/11/12追記:と、思ったけど
ブログの記事にしようと思ったけど、大半が本のコピーになんるので、やめておく。
気になったハック
気になったハックだけメモしておく。
7. lddで共有ライブラリの依存関係をチェックする
14. c++filtでC++のシンボルをデマングルする
18. CとC++のプログラムをリンクするときの注意点
20. GNU/Linuxの共有ライブラリを作るときPICでコンパイルするのはなぜか
22. GCCのGNU拡張入門
26. TLS(スレッドローカルストレージ)を使う
31. main()の前に関数を呼ぶ
43. -ftrapvで整数演算のオーバーフローを検出する
44. Mudflap でバッファオーバーフローを検出する
45. -D_FORTIFY_SOURCEでバッファオーバーフローを検出する
46. -fstack-protectorでスタックを保護する
49. 64ビット環境で0とNULLの違いに気を付ける
50. POSIXのスレッドセーフな関数
55. Valgrindでメモリの不正アクセスを検出する
56. Helgrindでマルチスレッドプログラムのバグを検出する
70. libdwarfでデバッグ情報を取得する
72. オブジェクトファイルを自力でロードする
74. GNU lightningでポータブルに実行時コード生成する
76. sigaltstackでスタックオーバーフローに対処する
77. 関数へのenter/exitをフックする
82. straceでシステムコールをトレースする
84. JockeyでLinuxのプログラムの実行を記録、再生する
85. prelinkでプログラムの起動を高速化する
87. gprofでプロファイルを調べる
88. sysprofでお手軽にシステムプロファイルを調べる
89. oprofileで詳細なシステムプロファイルを得る
90. GDBで実行中のプロセスを操る
92. Cのプログラムの中でブレークポイントを設定する
93. Boehm GCの仕組み
95. Portable Coroutine Library(PCL)で軽量な並行処理を行う
96. CPUのクロック数をカウントする
99. 結果が無限大やNaNになる演算でシグナルを発生させる
HTMLParserを使ってページのタイトルを取得
発端
ページのタイトルタグを取る必要があったので、正規表現で書こうかと思ったけど諦めた。理由はtitleタグには改行とかコメントアウトされている可能性があるから。
<title> タイトルだよー </title> --------------------------------------------- <!-- <title>偽タイトル</title> --> <title>こっちが本物のタイトル</title>
解決策
Python標準ライブラリ内にHTMLパーサのないかなと思って探したらHTMLParserというライブラリが見つかった。これを使いページのタイトルを取得してみた。
下記と同じ物HTMLParserを使ったページタイトルの取得 · GitHub
from HTMLParser import HTMLParser import urllib2 class GetTitle(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.title_flag = False def handle_starttag(self, tag, attrs): if tag == 'title': self.title_flag = True def handle_data(self, data): if self.title_flag: self.title = data self.title_flag = False def main(): url = 'http://twitter.com' response = urllib2.urlopen(url) gt = GetTitle() gt.feed(response.read()) gt.close() print '%s - %s' % (url, gt.title) if __name__ == '__main__': main()
参考文献
簡単なHTMLParserについて知れた htmllib.HTMLParserでリンクを抽出 - ひきメモ
gitで特定のファイルの履歴を消す方法
$ git filter-branch --index-filter 'git rm --cached --ignore-unmatch targetfile' HEAD
これで、特定のファイルtargetfileの履歴を消去できる。
特定のディレクトリは
$ git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch dir' HEAD
で特定のディレクトリdirが消える。-rオプションを忘れずに。
後は、コミットするだけ。
$ git commit -m 'delete targetfile'
リモートのリポジトリにもこの変更を反映させなければならない。
そういう場合は
$ git push origin master --force
でプッシュ。--forceを付けたのはリモートを強制的に上書きするため。
まだ、リモートにはブランチがのこってるので、それを消去
$ git branch -d delete-branch $ git push origin delete-ranch
参考サイト
特定のファイルの履歴を消す方法 : Redirecting...
リモートのbranchを消去する方法 : Git で不要になったローカルブランチ・リモートブランチの削除 - sotarokのお勉強