2012年3月15日木曜日

Django on HerokuでFacebookアプリを開発するためのTips集〜Heroku編〜

最近、アルバイトでDjango+HerokuでFacebookアプリを作っている。 その過程で、開発しやすい環境を構築するために気づいたことをメモ

はじめに

Herokuの 公式チュートリアル は非常に充実しています。 まずは公式チュートリアルをしっかり読みましょう。 そうすれば、デプロイまではすらすらできるはずです。

データベースの設定

Herokuでは、デプロイ時に勝手に使用するデータベースをHerokuのデータベースに書き換えてくれます。

というわけで、settings.pyには気にせずローカルのデータベースの設定を書きましょう。

一応、HerokuはPostgreSQLを使っているので、 ローカルではPostgreSQL、もしくは設定が簡単なSQLite3を使うのがお勧めです。

環境変数を使おう

やはり、実際に開発を行うとなると、本番環境だけでなく、ローカル環境や、更にステージング環境も必要になります。 また、Fabebookアプリの開発となるとサーバーだけでなくアプリも本番用と開発用を用意する必要が出てきます。

そんな時に、DEBUGモードの切り替えやアプリIDを書き換えをいちいち手動で行なっていたのでは事故のもとですし、 なにより面倒くさい!

というわけで、こんな時に役に立つのがHerokuの環境変数設定機能。 環境ごとに変更が必要な情報をすべて環境変数から受け取ることで、イチイチ書き換える手間を省こうということです。 Herokuでは、

heroku config:add *変数名* = *値*

とすることで環境変数を設定できます。 これは、完全に一般の環境変数と同じなので、

>>> import os
>>> os.environ[' *変数名* ']

で参照できます。 これを使って、settings.pyにて、

>>> FACEBOOK_APP_ID = os.environ[' *変数名* ']

などとしておけば、1度環境変数を設定してしまえば、後は自動で書き換えてくれるわけです。 参考: Herokuで認証付きのステージング環境を構築する

foreman を使おう

先ほどの環境変数の設定の話を聞いて、「ローカルでも環境変数設定しないといけないの?」とか、 「それだと、他のアプリの環境変数とかと衝突するんじゃない」とか、思ったかもしれません。 そこで、役に立つのがforemanです。

sudo gem install foreman

でインストールできます。 チュートリアルを読んだ方であれば、途中で出てきたので見覚えがあるかもしれません このforemanの便利な機能として、同じディレクトリに .env ファイルを入れておき、

foreman run *コマンド*

とすれば、そこに書かれた環境変数を設定した上でプログラムを実行してくれます。 .envファイルは単純で

*変数名* = *値*

をどんどん並べていくだけです。たとえば、こんな感じになります。

RACK_ENV='local'
FACEBOOK_APP_ID='1234567891234'

これを設定した上で、

foreman run python project/manage.py shell

のように使います。

ここで、少し注意。

コマンドに引数が必要なとき、

foreman run python project/manage.py syncdb --verbosity=2

などとすると--verbosityがforemanの引数として扱われてしまい、うまく動作しません。 なので、

foreman run 'python project/manage.py syncdb --verbosity=2'

のようにしましょう。

パスの設定

>>> TEMPLATE_DIRS = ('/home/user/mysite/templates/', )

のように、絶対パスで指定してしまった場合には、当然、デプロイ後にはHerokuのサーバー上でのパスに書き換える必要が生じます。

ですが、正直、Heroku上でのパスを調べるのは非常に面倒ですし、いちいち書き換えるのも面倒です。

と、言うわけでPython側で動的に生成してもらいましょう。settings.pyに、

>>> import os
>>> SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
>>> TEMPLATE_DIRS = (os.path.join(SITE_ROOT, 'templates'), )

のように記述すれば、``SITE_ROOT = os.path.realpath(os.path.dirname(__file__))``の部分で、 Djangoのプロジェクトのルートディレクトリを自動で取得してくれるので、もう書き換える必要はありません。

基本的に、絶対パスが必要な部分については、すべてこのように書くと便利です。

参考: Django 開発初心者に送る 10 の Tips (超訳?)

データベースの変更

Djangoは、モデルのスキーマの更新を自動で反映してくれないので、 意外とデータベースを直接操作しなければならない局面も多いです。

Herokuの最大の弱点は、無料プランだと、データベースを直接叩く方法がなく、 Heroku側で作業しようとすると、pythonのシェルを通して、ちまちま調整するしかないです。

ですが、その代わり、Herokuにはデータベースをローカルにコピーする機能と、 ローカルのデータベースをアップロードする方法が提供されています。これを利用します。 ここでは、tapsを用いた方法を紹介します。まずは、tapsをインストールします。

sudo gem install taps

では、データベースを取ってきてみましょう。

heroku db:pull sqlite://local.sqlite3

これで、Herokuのデータベース上のデータがローカルにコピーされます。 これを編集して、Heroku側にアップロードするときは、

heroku db:push sqlite://local.sqlite3

で、できます。当然ながら、元のデータベースは上書きされるので気をつけて下さい。

参考: Importing and Exporting Your Data Using Taps

もっと簡単にデータベースの変更

とはいっても、いちいちデータベースをまるごとコピーしていたのでは、時間がかかりすぎます。

要するにDjangoがHeroku側で勝手にモデルのスキーマを更新してくれれば万事解決するわけです。 なので、その機能を提供するDjangoプラグインの django-evolution を使用します。 導入は超簡単で、

pip install django-evolution

で、インストールし、settings.pyのINSTALLED_APPSに、 django_evolution を追加します。 そして、モデルのスキーマを更新したときは、

heroku run 'python manage.py evolve --hint --execute'

と打ち込むだけで、モデルの更新が完了します。

注釈

Djangoのプラグインでこのような機能を提供するものには、もうひとつSouthというものもあるのですが、 スキーマの生成方法を記述したファイルを一度ローカルに作成しなければならないため、 ファイルの書き込みができないHerokuでは少し使用するのが難しいため、こちらを使用しました。

2012年1月14日土曜日

軽量で扱いやすいVHDL環境ーGHDL

最近、Macに乗り換えたのですが、課題でいつもVHDL環境として使用していたModelSimは、 Macにだけ対応していないという嫌がらせのような仕様だったので (まあ、もともとModelSimはごちゃごちゃしていてあまり好きではなかったのですが) この際、別のソフトを探して見ることに。すると、GHDLというVHDLコンパイラと、 波形シュミレータのGTKWaveを使用する方法をみつけました。

導入方法はとても簡単で、Linuxなら、

sudo apt-get install gtkwave ghdl
で、一発で導入できます。Macなら、
sudo port install gtkwave
で、gtkwaveを導入したあと、本家サイトのこちらから ダウンロードできます。(ただし、gtkwaveはウィンドウのシステムにgnomeを使っているので、びっくりするぐらい時間がかかります。)

使い方は、VHDLソースコードのコンパイルは、

ghdl -a hoge.vhd test_hoge.vhd
そして、シュミレーションファイルの生成は
ghdl -r test_hoge --vcd=hoge.vcd
シュミレーションの生成時にはtest_hogeのみで.vhdはいらないので注意してください。 この場合、hoge.vcdがシュミレーション結果として出力されるので、
gtkwave hoge.vcd
で波形を確認できます。ただし、最初っから表示されてるわけではないので、 右端のボックスから表示する信号を選んで"Append"をクリックし、 さらにこのままだと、倍率が高すぎるので、右上の虫眼鏡のマークをクリックして大きさを調整します。

なんか、その気になれば、eclipseとかで、この開発環境を構築したりもできるようです・・・  ModelSimの開発環境が気に食わんという方はぜひお試しください。

2011年12月25日日曜日

LaTeXを更に手軽に書けるようにしてみた@MilkTeX

個人的にひっそりと開発しているLaTeXのトランスコンパイラMilkTeXですが 、実験レポートを書いていて不便だった点をいろいろと改良しました。

表のセルを直感的に結合

LaTeXで表のセルを結合しようとするとmultirowを使って
\begin{tabular}{|c|c|c|}
\multirow{3}{|c|}{結合}\\
a & b & c \\

のように書かなくてはならないのですが、なんともわかりにくい!

というわけで、「+」を使って、直感的にセルを結合できるようにしてみました。 セルの区切りに「/」ではなく、「+」を使用するとそのセルを結合します。 更に、+を左に固めれば左寄せ、右に固めれば右寄せになります。

@tabular |c|c|c|:
    --
    1/2/3
    左寄せ++
    ab+/c
    +中央寄せ+
    d/e+f
    ++右寄せ
    gh+/i
    --

特殊単語でいろいろ手軽に記述

先頭が特殊な記号で始まる単語(次の空白文字までの部分)が、勝手にLaTeXタグに変換されます $で始まる単語は、引数を取らないタグになります。要するに\latexみたいな記号を 前のバージョンより、手軽に書けるようになりました。

数式モード中で先頭が_, ^で始まる単語は添字として扱われます。

更に先頭が -> で始まる単語はラベル参照となります。

  • @latex;=$latex→\latex
  • a_x, a_x+1 ^2 , a_x_k+1 →a_{x}, a_{x+1} ^{2}, a_{x_{k+1}}
  • 図->label→図\ref{label}

題名とラベルの指定を一括

なにかブロック要素の後に題名とラベルをつけるのはよくあることなので、 @figure<題名|ラベル> []のように指定することで勝手に題名とラベルを付けてくれます。

startdocumentタグ

documentタグのブロックのために、延々タブを1つ下げつづけるのは面倒なので、 startdocumentタグを用意しました。@startdocumentと書いた後は、ファイルの終わりまで、 自動的にdocument要素として出力されます。

サンプル

実際にどんなふうに変換されるか、サンプルはこちら

2011年12月24日土曜日

Google Bookmarks 拡張機能比較!

実験のレポートで忙しいのですが、どうも忙しいと片付けをしたくなるもの。。。特に最近は実験に限らずwebで調べながら作業することも多いので、見たいページを放置してたら、タブが30個なんてこともザラになってきました。こんな時こそ、Bookmarkをうまく活用したいものですが、 ChromeデフォルトのBookmarkはあまりにも使いにくい・・・。GoogleBookmarkもそのままだとごちゃごちゃしてる上、登録するにも何するにもページを移動しまくらなきゃなりません

なので、使いやすいBookmark用のエクステンションを探してみることに

ひとまず、評価がそこそこの拡張機能を落としまくってみました。どうせ無料だし。 個人的に評価基準として重視したのは、

  • ページを移動しなくていいか
  • 検索しやすいか
  • 見やすいか
  • 手軽さ
ってなとこです。

シンプル Google ブックマーク★★

個人的な感想としては微妙・・・検索もできませんし、振り分けも単純にタグで分かれてるだけです。ついでに登録画面も別で開いちゃいます。オプションもソート順序のみ。ただ、タブが開くときのうにゃっとした感じとか、デザインは個人的に結構好きです。

SimpleGoogleBookmarks★★★★

なかなかの使い勝手の良さです。登録もポップアップの中で行えますし、 特に素晴らしい点が、ラベルの扱いやすさです。登録時にも、既存のラベルをどんどんクリックしていけば、 すぐさまラベル付が完了しますし、検索時にも、ラベルをどんどんクリックするだけで複数のラベルで絞込み検索をかけられます。 このへんは、使った拡張機能の中で一番の出来でした。ですが、致命的な問題は、表示が割りとあちこち崩れていることと、 ページ名を登録時に自動で読み込んでくれるのはありがたいのですが、読み取り方がかなり雑で、 アドレスがそのまま登録されたり、変なところに改行がはいって登録されて表示がめちゃくちゃになったりします。 このへんが無ければかなりいいのに・・・残念。

Google bookmarks★★★★★

かなりおすすめです。デザインも綺麗ですし、操作性もよく、スイスイ動きますし、登録・検索・移動をすべてポップアップの中でこなせます。 こちらはデザインが崩れることもありませんし、登録も正常に行えます。当然、ラベルの入力の補完も自動で行なってくれます。 欲を言えば、もうすこし、詰まった感じがなくなればいいのと、SimpleGoogleBookmarksの複数タグ選択機能が付いていれば完璧なのですが・・・。

BoogleMarks★★★★★

こちらもおすすめです。機能的にはGoogle Bookmarksとほぼ同じ。正直好みの問題かと。こちらのほうが、ブックマークをツリー形式で表示してくれるのでわかりやすい人はわかりやすい。あと、セッションを保存という謎の機能がありますが、ちょっと触っただけなのでよくわかりません・・・もしかすると、スゴイ機能なのかも・・・。オプションもかなり充実していますが、MouseOver機能はお勧めしません。ツリーが開きまくって、分けわかんなくなります(汗

Google Bookmarks Browser★★★

こちらも複数ラベル選択可能です。ただし、登録画面は別画面になります。SimpleGoogleBookmarkとくらべると、デザインはシンプルかつまとまっていて綺麗です。ただし、絞り込み時に選択候補から存在しない組み合わせを除外してくれないので、どの組み合わせのラベルが残っているのかよくわかりません。

まとめ

個人的には、Google bookmarksBoogleMarksがおすすめです。ただし、これらにはラベルの複数選択機能がないので、1つの拡張機能を使うことにこだわらずSimpleGoogleBookmarksあたりを併用すると、更に便利かもしれません。

2011年12月22日木曜日

さくらインターネットからpythonでメール送信

はじめに

仕事とは別件で、さくらインターネット共用サーバーでメーリスの自動登録システムを組んだのですが、 その時、メールの送信でつまずいたので記録しておく。

pythonで書いてありますが、他の言語でも参考にはなるはず。


まず、基本的には、下記のサイトの
Pythonでメールを送信したい人のためのサンプル集

に書いてある方法を組み合わせれば大丈夫なのですが、いくつか注意点があります。

まず、さくらのSMTPサーバーは、一般的な25番ポートではなく587番ポートを使用します。 25番ポートからでも送信できるようですが、25番ポートは迷惑メールなどでよく使われるらしいので、587にしておくのが無難だと思われます。 そして、TLSという方式で認証を行なってから送信します。 まあ、要するに、上記のリンク中の「gmailを使って送信してみる」の方法で行えば問題無いのですが、 送信用のアカウント(メールアドレス)をどのように準備するかを紹介します、

送信用アドレスの作成

まずは、コントロールパネルにログインし、管理画面の「メールアドレスの管理」を選択します。

そして、メールアドレス名とパスワードを設定し、登録します。このとき設定したパスワードはのちのち使用するので、忘れないようにしてください。これだけで準備は完了です。

コードを書く

さて、いよいよ送信用のプログラムです。先程も述べたように、基本的には上記サイトの方法で問題ないですが、 設定が少し厄介です。まず、SMTPサーバーとの接続は、さくらインターネットのアカウント(なんとか.sakura.ne.jp)で行います。 そして認証は、先ほど作成したメールアドレス名と先ほど設定したパスワードを使用します。

あとは、上記のサイトに従って設定すれば、送信できます・・・と言いたいとこですが、じつは上記のサイトの「日本語を含んだメール」の設定には 不備があります。msg = MIMEText(body, 'plain', encoding)をmsg = MIMEText(body.encode(encoding), 'plain', encoding)に書き換えてやる必要があるみたいです。そうしないと、Unicode.DecodeErrorだったかなんかが発生します。また、この手のPythonで日本語を扱うシステムは、基本的に文字はすべてUnicode文字を使用するようにしたほうがよさげです。

参考

Pythonでメールを送信したい人のためのサンプル集
Pythonで日本語メールを送る。

2011年12月20日火曜日

今になってGAE+Djangoで開発を始めてみる

目的

とりあえず、最近、GoogleAppEngine + Django + FacebookAPIという、 わりとマニアックな環境で作業してて、情報の古さや、Google App Engine Helper for Djangoの中途半端な互換性に 苦しめられることが多いので、備忘録的な感じで気づいたことでも書いていこうと思う。
そして、どさくさに紛れて、自作アプリやらソフトやらの宣伝をしてやろうという魂胆

知っておくべきこと

導入したあとで、がっかりしないように知っておくべきこと、
  • ビューとURLの制御に関しては問題なし
  • データモデル(データベース操作)に関してはDjangoと互換性がない。
  • よって、Djangoのデータモデルを使用する機構も使用不可(authなども多分無理かな)
  • ただし、formに関しては互換性のあるモジュールが存在する。
GAEのデータモデルはかなり特殊なため、データモデル関連の機能はform以外全く使えません。 それに連動して、Django関連のライブラリも使えないものが多いです。 つまり、GAE上で今までにDjangoで作ったアプリを即動かせるぜ、ってわけじゃないので注意してください。

導入編

Google App Engine SDK for Python

ひとまず、本家のスタートアップサイトに従って、 こちらからGoogleAppEngineSDKを落として解凍します。 Django使うなら当然Pythonの方です。

Google App Engine Helper for Django

次に、ここ から、Google App Engine Helper for Djangoを落として解凍。実は、解凍したファイルそのものがGAE上で動くようにカスタマイズされたDjangoプロジェクトなので、cp -r なり何なりでディレクトリごとコピーして、適当に名前をつけます。ここではチュートリアルに従ってmysiteとでもしておく。

.google_appengineの設定

すでにDjangoに触った人なら、このまま、manage.py runserverで起動だ!と言いたいところですが、まだいくつかやることがあります。 まず、DjangoをGAE環境で実行するために、mysite下に.(どっと)google_appengineを自分で作ってやる必要があります。 .google_appengineディレクトリの先にGoogleAppEngineSDKが置いてあるものとして、そこからGAEのテストサーバーとか必要なファイルをとってきて、 実行してくれるわけです。じゃあ、解凍したGoogleAppEngineのディレクトリをまるごとコピーすればいいんだな、ってなるかもしれませんが、(別にそれでも問題ないはずですが)実際には、シンボリックリンクでオッケーみたいです。ln -s コマンドでもつかって、作っちゃいましょう。

ファイルの修正

2011年12月の段階では、地味にバグがあって、このままじゃ起動できません。appengine_djangoの__init__.pyの210行目あたりの、 appconfig, unused_matcher = dev_appserver.LoadAppConfig(PARENT_DIR, {})appconfig, unused_matcher, from_cache = dev_appserver.LoadAppConfig(PARENT_DIR, {}) に変更します。 どうやら、GAEの仕様が変わったのか戻り値の個数が変化して、バグっていたようです。

実行

さて、ここまでくれば、mysite下で、./manage.py runserverでテストサーバーを起動できます。 サイトによっては、Djangoのバージョンが・・・とか書いてありますが、現在のGAEはバージョン1.2のDjangoが標準で入っているので問題ないです。 localhost:8000/もしくはlocalhost:8080/にアクセスして、画面が表示されたら完了です。