Facebook いいねボタンの挙動を localhost で検証する
Facebook app 登録
まあしましょう
ドメイン設定が必要
app の設定で localhost とかだとなんかだめっぽかったので以下を参考にした
localhost環境で、Facebook のJavaScript APIでOAuth認証をする - Goodpic
testapp.com
この場合 Mac がローカルだからいいけど、自分の場合開発用の Ubuntu Server でやってるので Mac 側の hosts の設定は以下を参考にした。
VMware上で動くWebアプリにホスト側からアクセス | ゆーすけぶろぐ
# 開発用のVMのアドレス
192.168.56.101 local.testapp.com
そうえば hosts って設定してよしなにしたことなかった。
検証する
FQL(Facebook Query Language) を飛ばして確認する。使用ライブラリは (python)facebook-sdk
>>> import facebook >>> g = facebook.GraphAPI('token') >>> g <facebook.GraphAPI object > # Like する前 >>> g.fql('select like_count from link_stat where url="testapp.com"') [{u'like_count': 0}] # Like したあと >>> g.fql('select like_count from link_stat where url="testapp.com"') [{u'like_count': 1}]
どうやら機能していることがわかる
まあ
はい
Django でメールを送信と確認
メールを送信する。Python 標準モジュールやライブラリにもありそうだけど、Django 組み込みであるのでそれを利用する。
日本語1.4::メールの送信 — Django 1.4 documentation
つかう
ドキュメントのままです
from django.core.mail import send_mail send_mail('Subject here', 'Here is the message.', 'from@example.com', ['to@example.com'], fail_silently=False) # もうちょっとつかいまわしやすくする message = message subject = subject # to 部分はリストかタプルで指定 email_from = "atas@hoge.com" email_to = ("noreply@hoge.com",) send_mail(subject, message, email_from, email_to)
メールサーバーはとりあえず postfix をつかった
sudo apt-get install postfix sudo /etc/init.d/postfix start
とどきます
ダミーサーバーをたてる
いちいち全部自分宛にやるのもうっとおしいのでなんかないかな、と思ったら python の smtpd モジュールで DebuggingServer なるものがあるらしくて、そのままつかった
# sudo しないと動かなかった。権限の問題? sudo python -m smtpd -n -c DebuggingServer localhost:25
なんかダミーサーバーがうごいていないと思ったら、postfix が port 25 で動いてたので止めたらよかった
sudo /etc/init.d/postfix stop
内容はこんな感じ
---------- MESSAGE FOLLOWS ---------- Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: some message From: noreply@hoge.com To: atas@hoge.com Date: Wed, 17 Apr 2001 06:37:39 -0000 Message-ID: <20130417063739.10658.62373@dev> X-Peer: 127.0.0.1 高円寺5.5万円徒歩10分東向き部屋一人暮らし情報ください ------------ END MESSAGE ------------
ちなみに -m はモジュール、-c はコマンドってのはわかったけど -n ってなんだろう。
まあ
はい
grep/ack/ag でのエスケープがわからないなら直接文字列リテラル渡せばいいじゃない
適当にエスケープしてメタ文字消して置換しようとしたけど、正直よくわからなかった。たとえばこういうもの
Obj.objects.create(**kwargs)
こういうとき愚直に「. をエスケープして……あれ()ってクオートで囲むの……あれ……」とかやってた
別に単純な文字列のマッチでよかった
そういうときには grep なら -F, ag なら -Q というオブションがある
# grep grep -rF "Obj.objects.create(**kwargs)" ./ # ag ag -Q "Obj.objects.create(**kwargs)"
あとは煮るなり焼くなり
# -l でファイル出力して xrags で受け取る ag -lQ "Obj.objects.create(**kwargs)" | xargs sed -i "s/Obj\.objects\.create(**kwargs)/oyaoya/g"
Django のコマンドを作って定期的に実行する
なんてことはないが、ちょっとハマったのでメモ
Django でカスタムコマンドをつくる
単純なスクリプトならそのまま Python のスクリプトとしてつかえばいいとおもうけど、 Django のコマンドであること、またそれらのモデルとかと連携したり、まああと意味合い的にそっちにもたせたいとかあるとき、コマンドを自作できる。
日本語 1.0::アクションを自作する — Django v1.0 documentation
英語 1.5::Writing custom django-admin commands | Django documentation | Django
英語の最新版のほうがわかりやすい。
階層をつくる
リポジトリ/プロジェクト/アプリ/ とツリー構造があるとき、INSTALLED_APPS に通っているパスで management/commands をつくる。python なので __init__.py も忘れずに。
BaseCommand クラスを継承したクラスをつくる
例だと class Command(BaseCommand) としてつくってる。クラス変数にオプションやらなんやらを設定できる。引数は optparse ベースで現状 python 2.7 だから argparse なんじゃないのとおもったけど、PyPi にはそれっぽいライブラリをつくってくれている人はいる。
実際の処理をかく
自分の場合は def handle(self, *args, **options) は main と同じような扱いにして、あとは関数に分けた。logger とかそういうバッチ処理系のなんかはよしなにした。
動かす
ファイル名が実行コマンドになっている(クラス名ではない) ので python manage.py some_command で実行できる
pyhton manage.py some_command
crontab で動かす
定期的に実行するなら crontab はまあつかう。で、登録する。それはいいが、2つハマった。
実行ユーザーの登録
実運営的にどうするかはわからないけど、実行ユーザーを管理したい場合は crontab -u user -e で登録できる。だけど Ubuntu だと sudo する必用があったっぽくて、root 権限でしか動かせないかと思ってた。そんなことはなかった。
sudo crontab -u atas -e
でよい
virtualenv 環境
普段 Python 関係の開発だと virtualenv(pyvenv) は必須だと思うけど、シェルから簡単に叩ける virtualenvwrapper を使っていた。でも、cron の登録では workon など virtualenvwrapper のコマンドは叩けないよね、ってところで少しハマってた。なので直接 virtualenv を activate すればよい
. ~/.virtualenv/dev/bin/activate
つなげる
こうなる
# m, h, d, w, m, command * * * * * . /home/atas/.virtualenv/dev/bin/activate && cd /path/to/porject && python mamage.py some_command
もうちょっとちゃんとやるならシェルスクリプトにして
#!/bin/bash export DJANGO_SETTINGS_MODULE=mysite.settings . /path/to/virtualenv/dev/bin/activate cd /path/to/src python manage.py some_command
のほうがいいかもしれない
トラブルシューティング
Django のカスタムコマンドはつくれている前提で crontab での実行がどうなってるかがみえなかった
- 登録っぽいことをかく
- ログは /var/log/syslog に出るらしい
- crontab の設定自体は /var/spool/crontab/... にあるらしい(が、実ファイルを直接触ることは基本しないらしい)
- tmux でペインを分けてログを監視する tail -f /var/log/syslog
- ちなみに less で表示して shift f でも同じ事できるけど、圧倒的に普段は tail -f のほうがいい感じだった
- logger も動かしているのでそのファイルの状態も tail -f some.log してみる
- VM で開発しているのでたぶん大丈夫だけど時刻設定は date コマンドで確認する。1分を待つのが長い。
- ユーザーやなんやらでうごかなかったけど、結局はよく考えたら virtualenv 環境で環境のパスを実行ユーザーが見れないと困るよね*1、というようなところで解決
まあ
ある
*1:この記事をかいたときPYTHONPATH だと思ってたけど違った
Python の全角半角処理に zenhan が便利
バリデーションとか検索とか
だいたい全角半角でどうとか変換とかかませたりする。で、Python で有名なところだと zenhan というのがある。
つかう
公式にもあるけど、ヘルプ見た感じでも難しくない
import zenhan # バイト列 s = 'Foo' # unicode 型に変換 if isinstanc(s, str): s = s.decode('utf-8') # 全角から半角に変換 s_hankaku = zenhan.z2h(s) print(s_hankaku) # Foo
いいですね
英数字だけ変換したい
ちょっとはまったのは、日本語部分は別にそのままでいいんだけど英数字だけ変換したいしたいということだった。オプション指定すればいいだけだった
help(zenhan) FUNCTIONS h2z(text, mode=7, ignore=()) # function convert from HANKAKU to ZENKAKU # argument and return: unicode string z2h(text='', mode=7, ignore=()) # function convert from ZENKAKU to HANKAKU # argument and return: unicode string DATA ALL = 7 ASCII = 1 DIGIT = 2 KANA = 4 __version__ = '0.4' VERSION 0.4
ということで、この場合 3 をしていてやったらうまくいった
はい
ありがたや