programing
2012年08月18日
sinatraを一から勉強し直している。
Ruby on Railといったフレームワークをちゃんと使ったことがないから、理解していないことが多すぎる。
ということで、sinatraの基本的な使い方として、以下をまず始めに学ぶことにした。
- deply環境の切り替え方法
- auto reloadを使えるようにする方法
auto reloadは、ソースコードを変更したとき、アプリケーションサーバを起動し直さなくても、自動的に再読み込みをしてくれるので、try&errorをするときの作業効率が全く違う。是非早めにマスターしておきたい。
deploy環境の指定ができるようになると、プログラム中で環境に応じた処理を分岐させることができる。
開発環境では、reloaderを有効にするが、本番環境では無効にするとか、開発環境の場合にdebug用の出力を出す、とかを簡単に切り替えられて楽になる。
で、いきなりつまずいた。
sinatraでのdeploy環境は、以下の3つから選択することとなる。
- 開発環境:development
- テスト環境:test
- 本番環境:production
環境を指定するには、コードの最初の方で以下のように宣言しておく。
|
環境の指定は、rubyを実行する時の-eオプションで指定することもできる。
|
使い方は、それ以降でdevelop?もしくはproduction?メドッドで判別し、trueかfalseが返るので、それで条件分岐させる。
|
このdevelopment?やproduction?やtest?というメッソッドは、sinatra/base.rbの中で以下のように定義されている。
|
さて、このenvironment変数に入っている環境指定のシンボルをどうやって参照するかも試した。
マニュアルによれば、settings.environmentで取れるはずだ。
しかし、settings.environmentで得た結果と、production?で得た結果が異なるのである。
例えば、以下のようなコードでは。
|
出力はこうなる。
|
一方、以下のようにclass定義内にset文を入れると、
|
このようになる。
|
この違いがわからないまま、今に至る訳である。
class定義の外でsetしたものはクラス変数に入り、内側でsetしたものはインスタンス変数に入るのだろうか。
そして、settingsはインスタンス変数を見ているが、?メソッドはクラス変数を見ていると考えれば、合点はいくが、なぜそんなふうになっているのかは謎。
実用上は、production?メドッドで分岐させることが多いはずなので、classの外側で定義しておけば問題ない。
また、ruby起動時の-eオプションで指定した場合も、前者(classの外側で定義)と同じ動きをする。
ややこしいことに、configure 〜 do は、内側で定義した:environmentで判断されるようだ。
では、外側で定義した:environmentの値を、内側の:environmentに代入するような仕組みにすればいいかと思ったが、どうもそれもうまく動かない。
結局、rubyの思想に反するが、両方で定義しておくのが安定しそうだ。
ちなみに、reloaderの読み込みは、上記コード内のconfigureブロックの中で書いてあるとおり。
参考は以下。
2011年02月17日
google app engine上でEvernote連携のwebサービスを作るには、OAuthでの認証が必要になる。
このエントリーでは、OAuthをGoogle AppEngine上でpythonを使って認証するサンプルプログラムcunsumer_oauth.pyを提供する。
OAuthの直接的な部分は、google codeで提供されているoauth.pyを使い、それの呼び出し方を記述しているのが、consumer_oauth.pyである。
このプログラムは、oauth.pyのライブラリの使い方の参考とすることを目的としているので、元のoauth.pyライブラリに則り、MITライセンスとする。
oauth.pyを使ったサンプルプログラムは、webで調べるとtwitter向きのものが多い。
しかし、Evernoteをproviderとしたとき、同じOAuthでも、twitterとevernoteではパラメータの扱いが若干違うため、そのままは使えない。 そのあたりを修正して、ここにあげておく。
1. OAuthの仕組み
まずは、OAuthの基本的な動きを理解する。
- ゆろよろ日記:OAuthプロトコルの中身をざっくり解説してみるよ
- EvernoteのOAuth仕様を 公式ページで勉強する
2.ライブラリの入手
google codeでは、pythonのOAuthライブラリが ここ で公開されている。
ここでは、exampleとしてoauth.pyを使った client.py というのもあるのだが、これがどうもわかりづらい。
いろいろ探っているうちに、わかりやすいexampleをみつけた。
このexampleは、いろいろミスがあり、動かすためにはかなりの修正が必要となるが、oauth.pyの使い方はとても参考になった。おかげで、oauth.pyを使えたといっても過言ではない。
3.EvernoteからAPI keyの取得
実際に、以下のプログラムを動かすには、Evernoteからconsumer用API keyを入手しなくてはならない。
以下のフォームからEvernoteにAPI keyを申請する。https://www.evernote.com/about/developer/api/
application typeは"web application"とすること。
1,2日でメールで届くはずである。
4.Evernote OAuthの特徴
Twitterなど、あちこちで公開されているOAuthの使用例と比べて、Evernoteでは、以下の2点を注意する必要がある。
- twitter OAuthなどでは、request tokenからaccess tokenに交換するために、承諾されたoauth_okenを送るが、evernoteの場合は、同時にverifierも送らないといけない。
verifierは、エンドユーザが承諾ボタンを押した後のcallback urlで戻ってくるhttp getリクエストの中に、パラーメータとして格納されている。 - 承諾画面より後はevernoteではoauth_secretを使わないので、url encodeされたパラメータ部分で&oauth_secret=&、と値部分がnullになるリクエストが一度だけくる。
1.については、verifierパラメータを抜き出して、リクエストURLを生成時する関数にパラメータを渡すことで対処できる。oauth.pyのライブラリは、verifierをリクエストに加える機能を持っている。
2.については、secretパラメータがnullになるとoauth.pyの中でエラーとなる。ouath.pyの以下の行でエラーを補足し、secretにダミーの文字列をセットすることで対処する。
5.oauth.py変更箇所
137行目から
|
|
6.Access Tokenの保存
consumer webサービスを使うたびに、毎回evernoteで承諾をするのが面倒なので、承諾済みであることをどこかに記録しておきたい。
クッキーを使ってブラウザに保存する方法と、consumerサーバ上に保存する方法がある。
今回作成したconsumer_oauth.pyでは、google app engineのデータストアに保存することにする。 そのため、consumerサービスを使うときは、googleアカウントでのログインを必須とし、GAE上のデータストアにgookeアカウントにひもづくEvernote access tokenを保存することにした。
本当のwebサービスでは、プライバシー保護としてaccess tokenを保存しないオプションを用意する予定である。
7.consumer_oauth.pyの実行
変更済みのoauth.pyとapp.yamlもセットにして、consumer_oauth.pyをgithubで公開したので、以下からダウンロードする。
GAE開発キットが動作する環境であれば、githubからダウンロードした3つのファイルを同一ディレクトリにおいて、開発サーバを起動すれば、ブラウザからアクセスできる。
注意点は、以下の2点である。
- evernote開発環境のアカウント Evernoteでの承諾は、evernoteログインが必要である。(当然だが) このプログラムでは、URLをEvernoteの開発サーバ(sandbox.evernote.com)に指定しているので、本番サーバ(www.evernote.com)のアカウントとは別に、開発サーバ用にユーザ登録をしないとEvernoteにログインはできない。
- Callback URL callback URLは、GAE開発環境(localhost:8080)をデフォルトとしている。GAE上にアップロードする前には、.appspot.com名のホスト名に修正してからアップロードする必要がある。
正常に動作すれば、以下のような画面がブラウザでみれるはず。
1.googleにもEvernoteで承認されていない状態
2.Googleにログインし、Evernoteで承認されていない状態
3.Evernoteで承認する画面
4.Evernoteに承認された状態
これ以降、このoauth_keyをEdamに格納し、Edam_userIdのディレクトリに向かってAPI を呼び出す部分を作ることで、consumerからノートの操作が可能となる。
|
2010年12月10日
pythonでJPEG画像のEXIF情報を扱うのが、けっこう手間取ったので、ここに記しておく。 pythonの日本語情報は、表面的なものはあるけど、ちょっと突っ込んだものはやはり少ないと実感。
exif.pyというライブラリもあるが、追加ライブラリを使わずにやりたかったので、Python Image Libraryを使う。
|
_getexif()で取得したEXIF情報は、DICT型になっている。そして、各要素のKEYは、int型になっているため、このままでは何が何の情報なのか、さっぱりわからない。
ちなみにvalue側は、タプルだったり、stringsだったり、いろいろ違うようだ。ややこしい。
|
そこで、exiftagsというモジュールで、要素の名前に変換してやる。
|
出力は、こんな感じ。
|
なお、37500のexif要素には、何やらバイナリデータが入っていたので(サムネイルか?)、出力をはじいています。
- ブログネタ:
- pythonプログラミング に参加中!
2010年11月19日
rubyをあきらめて、勉強をはじめてみた。
基本構文に慣れるために、簡単な数あてゲームを作った。
コンピュータが乱数で答えを決めて、ユーザに数字を入れさせて、もっと大きくとか、ヒントを出していくもの。
BASICの時代によく作っていたような、単純なものだ。
ルールは以下の通り。
- 答えの値の範囲は、1から100までの間。(冒頭の変数で最小値と最大値は容易に変更できる)
- 正解のプラスマイナス5の範囲に入ったら、”もうちょっと”という表現を使い、推理のヒントにする。
- 正解後、入力履歴を表示する。
コーディングには、以下の点に気をつけた。
- 正しく日本語を扱う
- 入力エラーを厳密に判断する
pythonの特徴は、可読性の良さと、誰が書いても同じようなコードになることだという。
どうでしょうか?
|
実行結果は、以下のようになる。
|
2010年10月28日
うちの2番目ちゃんと3番目ちゃんは、数字が読めるようになり、足し算もわかってきたようだ。 小学生の1番目ちゃんは、割り算や分数も習ったようだ。
一方、ぼくはjavascriptを使ったドラッグアンドドロップを勉強しようと思っていたので、 数字のブロックを組み合わせて四則演算の数式を作って遊ぶアプリを作った。
平日の夜や土日にちょこちょこと勉強しながら作る日曜プログラマなので、 完成まで実に三ヶ月くらいかかってしまった。
せっかくwebアプリなので、iPadやiPhoneのsafariでも動くようにしたほうが、子供にはうける。 そう考えたことが苦労のはじまりであり、結局、 safai対応にするのに二ヶ月余計にかかったと言っても過言ではない。
PCかiPad/iphoneかは自動で識別するので、以下のURLにアクセスするだけで遊べる。 例によってGAE上で動いているが、HTML/Javascriptのファイルを配ることにしか使っていない。 表示されたブロックをドラッグして、任意の数式を作ってほしい。=をおいて、右辺と左辺が等しくなれば、 ハナ丸が表示される。教育目的であるから、計算も自分でして、正解かどうかをフィードバックするものだ。
http://numericblocks.appspot.com/
PCのブラウザでは、マウスのイベントは"mousedown"や"mousemove"で取得できる。 一方、iPad等のタッチ操作は"touchstart"や"touchmove"という別のイベントである。 しかも、単なるイベント名の置き換えではなく、挙動が違うようだ。
今でも解決できていない問題は、touchして、ブロックオブジェクトを生成・表示したあと、 指を離さずに移動させたとき、新たに生成したブロックが動かないという問題。
しかたなく、iPad/iPhoneでは一度ブロックをタップしてブロックを生成し、改めてその ブロックをタッチして移動する、という仕組みにせざるを得なかった。
この解決ができる方、是非、教えていただきたい。
HTML5でドラッグアンドドロップが標準サポートされた。
はじめは、 それを使ってアプリを作れば、HTML5対応をうたうiPad safariで、そのまま使えると思いこんでいた。 しかし、それほど甘くなく、当然ぴくりとも動かない。イベントが違うので当然である。
jQueryをはじめとする、多くのjavascriptライブラリでも、ドラッグアンドドロップの 仕組みが提供されている。が、iPad safariと互換のあるものを見つけることができなかった。 そこで、改めてsafariのタッチイベント関係を調べてみると、最も基本的なstart、move、endしか ない。
PCとiPad safariを互換させたプログラムとすることを考えると、 PCのマウスイベントもdown、move、upの基本イベントのみで記述し、それをタッチイベントと 置き換えるようにしなければならない。でないと、共通部分が少なくなってしまい、別々に専用の プログラムを作るのと変わらなくなってしまう。 ということで、HTML5のドラッグアンドドロップを使うことを捨てて、再度作り直した。
その他、いままでイベント駆動型のプログラムを書いたことがなかったため、実に多くの試行錯誤を 繰り返し、何度も書いては捨ててることとなった。 結局、8月初めから作り始めて、途中、机やタンスを組み立てたりしながら、三ヶ月かかってしまったのだ。
そして先日、子供たちに遊ばせてみたのだが、はじめこそ遊んでくれたが、さほど盛り上がらなかった。 まぁ、そんなものである。
- ブログネタ:
- JavaScript に参加中!
2010年10月23日
少し前まではsubversionとかが使われていたらしいが、最近はgitが定番になっているようだ。
Linux Kernelの開発にも採用され、githubという(いまのところ)フリーで使えるサービスもある。
ぼくのような趣味でやっている日曜プログラマには、バージョン管理など不要であるが、ソースを公開するのには便利そうなので使ってみることにした。
ブログでソースを公開するとき、HTML的に適切でないコード(不等号記号やら)が入っていると、ブラウザが正しくソースを表示してくれない。そのため、あらかじめそうした記号は、HTML的に正しく表示できるように変更しておく必要がある。
こうした便利なサイトもあるので利用しているが、それでもけっこう面倒だ。
githubのような、こうしたソースファイルを管理してくれて、ダウンロードの仕組みがあるのはうれしい。
ということで、以前作成した、rubyスクリプト「RMagickを使った画像加工ツール群」をgithubにuploadした。
http://github.com/yasuki/rmagick-tools
以下は、githubを使えるようにするまでのメモ。
詳しくは、以下のサイトで勉強してください。(ぼくもまだ、よくわかっていない)
http://d.hatena.ne.jp/pneumaster/20090615/1245045677
http://d.hatena.ne.jp/keita_yamaguchi/20080409/1207752188
1.事前準備
使う端末に、gitコマンドをインストールする。
|
githubとは、sshでファイルをアップロードするので、ssh key pairを作っておく。
後ほど、この公開鍵を、githubに登録する。
|
パスフレーズもちゃんといれる。
~/.sshの下に、id_rsaとid_rsa.pubができるので、id_rsa.pubが後ほど登録する公開鍵。
2.サインアップとリポジトリの作成
http://github.com/ にアクセスし、sign up。ログインをして、dashboardを見ると、Create a Repositoryというのがあるので、そこで公開したいソースファイルのリポジトリを作成する。
3.アップロードテスト
すると親切に、次に何をするかを教えてくれる。アップロードしたいファイルを入れるリポジトリ用のディレクトリを掘り、
そこをカレントディレクトリとして、以下のコマンドをいれる。
|
すると、READMEファイルがgithubのリポジトリにアップロードされた。
4.アップロード
いよいよ、公開したいソースファイルをアップロードする。上で作ったディレクトリに、アップロードしたいファイルをコピーし、以下のコマンドを入れる。
|
- ブログネタ:
- Rubyプログラミング に参加中!
2010年08月18日
GAE上にてsinatra+OAuthでtwitterを扱えるようになったので、入力したtweetを、逆順にしてpostするwebアプリケーション「Right to Left twitter」を作った。
とりあえず動いている、というレベルなので、とてもじゃないがソースは晒すことはできない。もっとエレガントに書けるようになりたい。
「こんにちは」と入れると「はちにんこ」と変換してpostされる。
回文モードもあり、「しんぶんし」であれば「しんぶ」と入力することで、「しんぶんし」を作ってくれる。
真ん中の文字を、重ねるオプションもあり、「しんぶ」と入力して重複させると「しんぶぶんし」となる。
いや、だから何の役に立つってわけじゃないけどね・・・。
http://rtl-maarui.appspot.com/- ブログネタ:
- Twitter(ツイッター)について に参加中!
GAE上のjrubyプログラムでクライアントからの値を取れるようになったので、次はいよいよ他のサービスとの通信だ。 しかし、他のサービスとの通信をするには、認証という大きな壁がある。
一番簡単そうなtwitterで遊んでみることにする。
twitterは、今月(2010-08)にbasic認証を終了するとアナウンスしているので、oauthを使う。 oauthのお勉強はこちらなど。
まずは、環境の確認の意味で、こちらのプログラムを動かしてみる。
しかし、なかなか素直に動かない。
試行錯誤すること3日。
あちこちを参考にするが、つまづきまくる。
結果としては、原因が2つあったようだ。
一つは、appengine gemでjrubyへライブラリを組み込むとき、appcfg.rb bundleをするが、gemの依存関係の処理がうまくいっていないようだ。 依存gemをGemfilesに書いてあげることで、gemのloadはクリアできた。
二つ目の原因は、twitter gemとoauth gemの2つをrequireしていたのだが、twitter gemにoauthのクラスが組み込まれており、oauth gemと競合していた。require twitterのみにして解決した。
あと、GAEの特徴として、Net::HTTPが素のままでは使えないという問題もあるが、これもgoogle-appengineが解決してくれているので、今や意識しなくてよいようだ。
動作環境は以下。
|
Gemfilesとrequireリストは、以下になる。
|
$ cat sample.tw.rb |
- ブログネタ:
- Rubyプログラミング に参加中!
2010年08月12日
今回は、formを使って値を入力し、サーバ内でその値を取得することを目的とした。
input formに値を入れて、2の乗数を計算して出力している。
計算は、javascriptによりクライアント側で計算するものと、rubyにてサーバ側で計算することの両方を行っている。
xを100を程度の大きな値にすると、数値表現に差異が出ておもしろい。
http://jrubyhw-maarui.appspot.com/
ちなみに、異常に大きな数値を入れられて、無駄な計算を行うのを避けるために、256以下の入力にしてほしい。
HTML5に対応しているブラウザでは、257以上の数値は入れられないようにしている。
URLは、あまりにセンスのないものであるが。
今のGAEではアプリケーションの数が10個までと制限があるにもかかわらず、一度登録したアプリケーションを削除ことができないので、実験URLをリサイクルしている。
2010年08月06日
もじもじくん
はじめてまともにjavascriptを書いてみたが、やはり難しい。
Javascriptだけ考えればいいわけではなく、HTMLと、CSSも書いていく。
ある働きを記述したいときに、CSSでもjavascriptでも表現可能な場合、どこで記述するのがいいのか、余計なことを考えすぎる。
慣れていくしかない。
うちの2番目ちゃんや、3番目ちゃんは、ひらがなを読むことはできるが、書くのを練習中。
ときどき「ふぁ」ってどう書くの? とか聞かれるので、このページで字を大きく表示して教えてあげるような使い方を想定している。
iPhoneやiPadのブラウザでも動作する。
日本語も入力できるので、1番目ちゃんに漢字を聞かれても大丈夫。
入力できる文字数は、16文字まで。
- ブログネタ:
- Webアプリケーション に参加中!