vimでjslint

できるようにした。

jslint.vim にしようとしたけどうまいこと動かんかったので syntasticにした

http://superbrothers.hatenablog.com/entry/2012/03/04/155645

設定

$ npm install -g jslint
$ vim ~/.vimrc

NeoBundleで入れて

NeoBundle 'scrooloose/syntastic.git' 

javascriptのみ構文チェックを有効に設定

" syntastic "{{{
let g:syntastic_mode_map = { 'mode': 'passive',
            \ 'active_filetypes': ['javascript'],
            \ 'passive_filetypes': [] }
" }}}"

使いかた

これでjsファイルを開いたり、保存したりしたらlint checkが走る。

一覧の表示は

:Errors

強制的にチェックを走らせるのは

:SyntasticCheck

その他

色々、「え」ってところでエラーになったので勉強になった。

例えば

(function(){})();

じゃなくて

(function(){}());

とか。

あと

(function(){}).call(hoge);

(function(){}(hoge));

とか。

まぁ、諸説あるとは思いますが…

なんというか、勉強がたりませんな…

遅ればせながら bpython 入れた

最近は ipython より bpython らしいので遅ればせながら導入してみた

インストール

$ pip install bpython

このまんまでも使えるけど、諸々気になるところがあっていろいろいじった

キーバインド変えたい

F2のソースコード参照が動いてくれなかったので、変更したくなった

設定ファイルをいじった

.bpython/config でも読み込むけど、bpython/config.py にあんま使ってほしくない的なことが書いてあったので、.config/bpython/config の方に書いた

$ vim ~/.config/bpython/config

F2からCtrl-xに変更

[keyboard]
shor_source=C-x

Ctrl-hが効かない

以下の環境だと Ctrl-h 押すと改行されてしまってとてもつらい状態になった

直接パッチを当てた

http://blog.shironoo.org/2012/04/03/216

どうやら作者の都合でC-Backspaceを改行するようになっているっぽい。
それにCtrl-hも反応しちゃう(?)ので、そこを除外。

diff --git a/cli.py b/cli.py
index 26a9ba6..9aed92f 100644
--- a/cli.py
+++ b/cli.py
@@ -828,15 +828,10 @@ class CLIRepl(repl.Repl):
             C_BACK = chr(8)
             BACKSP = chr(127)

-        if key == C_BACK:  # C-Backspace (on my computer anyway!)
-            self.clrtobol()
-            key = '\n'
-            # Don't return; let it get handled
-
         if key == chr(27): #Escape Key
             return ''

-        if key in (BACKSP, 'KEY_BACKSPACE'):
+        if key in (BACKSP, C_BACK, 'KEY_BACKSPACE'):
             self.bs()
             self.complete()
             return ''

補完結果が崩れる

会社の Windows 環境で tmux とあわせて使っているとどうも補完結果の罫線とかが崩れてしかたがない

puttyの設定なおした

http://ptan.info/archives/384

どうやら putty の設定が間違ってたらしい

  1. 文字コードの設定を「UTF-8 (Non-CJK)」に
  2. CJK用の文字幅を使用する にチェック
  3. Unicodeライン描画コードポイントを使う にチェック

(1)の文字コードの設定が「UTF-8(CJK)」になっていたので変更したら直った

ついでにずっと気持ち悪いと思いながらも放置してきた「tigでスクロールしたときに残像が残って文字が読み難くなってしまう問題」もいくらか緩和されたような気がする

おわり

これでそれなりに使えるようになった。
ただ、ipython の ? 的な使いかたができないのがちょっとつらい、気がする

supervisor から solr を起動してプロセス死亡時に再起動するようにしたときのメモ (ざっくり)

supervisorの設定

systemのpythonに直接インストールする

$ sudo pip install supervisor
$ sudo mkdir /var/log/supervisor/
$ sudo mkdir /etc/supervisord.d/
$ sudo su - root -c "echo_supervisord_conf > /etc/supervisord.conf"
$ sudo etckeeper commit -m"Add supervisord.conf"
各設定ファイルを記述

supervisorのグローバル設定

  • /etc/supervisord.conf
diff --git a/supervisord.conf b/supervisord.conf
index a29252e..b076add 100644
--- a/supervisord.conf
+++ b/supervisord.conf
@@ -13,11 +13,11 @@ file=/tmp/supervisor.sock   ; (the path to the socket file)
 ;password=12311 @@ file=/tmp; (default is no password (open server))
 [supervisord]
-logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log)
+logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
 logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
 logfile_backups=10           ; (num of main logfile rotation backups;default 10)
 loglevel=infops=10           ; (log level;default info; others: debug,warn,trace)
-pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
+pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
 nodaemon=falseun/supervisord.; (start in foreground if true;default false)
 minfds=1024lseun/supervisord.; (min. avail startup file descriptors;default 1024)
 minprocs=200seun/supervisord.; (min. avail process descriptors;default 200)
@@ -128,4 +128,4 @@ serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
 ; include files themselves.
 [include]
-;files = relative/directory/*.ini
+files = /etc/supervisord.d/*.ini

solrの設定

  • /etc/supervisor.d/solr.ini
-;files = relative/directory/*.ini
+;files = /etc/supervisord.d/*.ini
diff --git a/supervisord.d/solr.ini b/supervisord.d/solr.ini
new file mode 100644
index 0000000..b8ca6de
--- /dev/null
+++ b/supervisord.d/solr.ini
@@ -0,0 +1,8 @@
+[program:solr]
+command=java -jar start.jar
+directory=/home/moqada/sandbox/apache-solr-3.6.0/example/
+stdout_logfile_maxbytes=50MB
+stderr_logfile_maxbytes=50MB
+stdout_logfile=/var/log/supervisor/solr.log
+stderr_logfile=/var/log/supervisor/solr_err.log
+auto_restart=true
起動確認
$ sudo supervisord
$ sudo supervisorctl status
solr                             RUNNING    pid 28985, uptime 0:05:41

topでもsolrとsupervisorが起動していることを確認

自動起動設定

supervisor自身の自動起動のためにupstartを導入

インストール
$ sudo yum install upstart
設定ファイル記述

/etc/init/supervisord.conf

diff --git a/init/supervisord.conf b/init/supervisord.conf
new file mode 100644
index 0000000..12bf7fa
--- /dev/null
+++ b/init/supervisord.conf
@@ -0,0 +1,7 @@
+description     "supervisor"
+
+start on runlevel[2345]
+stop on runlevel[!2345]
+
+respawn
+exec /usr/bin/supervisord -n
起動
$ sudo init start supervisord

killして再起動されるか確認

操作諸々

起動

$ sudo supervisorctl start solr

停止

$ sudo supervisorctl stop solr

再起動

sudo supervisorctl restart solr

設定再読み込み

$ sudo supervisorctl reread solr


最終的にsolrはmulticore起動するようにsolr.iniのcommandを変更

[program:solr]
command=java -Dsolr.solr.home=multicore -jar start.jar
directory=/home/moqada/sandbox/apache-solr-3.6.0/example/
stdout_logfile_maxbytes=50MB
stderr_logfile_maxbytes=50MB
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s_err.log
auto_restart=true

プロセス死亡時のメール通知設定

http://blog.hakutoitoi.com/?p=396

$ sudo pip install superlance

設定ファイルを追加
なんとなくそれように分割

/etc/supervisord.d/crashmail.ini

diff --git a/supervisord.d/crashmail.ini b/supervisord.d/crashmail.ini
new file mode 100644
index 0000000..743d9ec
--- /dev/null
+++ b/supervisord.d/crashmail.ini
@@ -0,0 +1,3 @@
+[eventlistener:crashmail]
+command=/usr/bin/crashmail -p solr -m example@example.com
+events=PROCESS_STATE_EXITED
起動、確認
$ sudo supervisorctl update
$ sudo supervisorctl status
crashmail                        RUNNING    pid 29422, uptime 0:03:54
solr                             RUNNING    pid 29429, uptime 0:03:23

killして確認してみる

メールが届いたらOK

django.contrib.auth.admin.UserAdmin の email をガラケーに対応させる

Djagno の EmailField は「.」 連続とか「@」の直前に「.」があるような、いわゆる日本のガラケー特有のRFC違反メールアドレスは問答無用で Invalid にしてしまう。

なので、ガラケー対応が必要な部分はそういうのを許容した validation を持つ Field を独自に定義して使ったりするんだけど、django.contrib.auth の UserAdmin で email の validate を変えたい場合はちょい一工夫が必要だったんでメモ。

ガラケー用のvalidatorを定義する

django.core.validators の validte_email を参考に適当なとこに RFC違反の "." 連続とかを許容した validator を作る

from django.utils.translation import ugettext_lazy as _
from django.core import validators

# ガラケー対応のEmail Validation
# ..@example.com とかでも OK になるけど、気にしない
japanese_email_re = re.compile(
    r"(^[-.!#$%&'*+/=?^_`{}|~0-9A-Z]+"  # dot-atom
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
validate_japanese_email = validators.EmailValidator(
            japanese_email_re, _(u'Enter a valid e-mail address.'), 'invalid')

普通の Form の場合は、これを利用して forms.py にこんな感じに定義して使う。

class JapaneseEmailField(forms.EmailField):
    default_validators = [validate_japanese_email]

UserAdminは置き換えるだけじゃダメ

あとは単純に admin.py で UserAdmin の form に上で作った JapaneseEmailField を含んだ Form に置き換えるだけで終了。

…と、思ってましたが…
UserAdmin は ModelForm を利用してるらしく、models.EmailField の default_validatorsが効いてしまってまんま置き換えるだけでは、普通の EmailValidator のままになってしまうよう。

clean_Field を上書きしとく

models の Field で定義された validators を無効にするために、clean_** メソッドを上書きして、admin.py で ModelAdmin を置き換える

from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin


class MyUserForm(forms.ModelForm):

    def clean_email(self):
        from django.core.validators import EmailValidator
        field = self.instance._meta.get_field('email')
        new_validators = []
        for v in field.validators:
            if isinstance(v, EmailValidator):
                new_validators.append(utils.validate_japanese_email)
            else:
                new_validators.append(v)
        field.validators = new_validators
        return self.cleaned_data['email']


class MyUserAdmin(UserAdmin):
     form = MyUserForm


admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

なんか、isinstance で判定してから無効にするって微妙な感じもするけど…一応これでガラケーアドレスでも admin で通るようになる。

なんか

一年以上前に書いた記事が下書きのままになってたんでとりあえず公開してみた
当時使っていたDjangoのバージョンはおそらく、1.2 だったと思う…

Celery を Django と Redis で使う

メッセージキューやりたくなったので

環境

インストール

django, celery, redis のセットで使う場合のパッケージ
$pip install django-celery-with-redis
redis
$sudo yum install redis

設定

redis起動
$sudo /etc/init.d/redis start
settings.pyに追記
import djcelery
djcelery.setup_loader()
BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis'

BROKER_TRANSPORTにdjangoも指定できるっぽいので
開発環境ではこちらの設定を適用できるようにしておくのも、ありかも

syncdb

south環境の場合はmigrate

$ python manage.py migrate djcelery
process起動
$ python manage.py celeryd --loglevel=info

テスト

サンプルどおりのテストプロジェクトを作ってためしてみる

startapp
$ python manage.py startapp celerytest
tasks.py作成
$ vim celerytest/tasks.py

tasks.py

from celery.task import task

@task
def add(x, y):
    return x + y
APPSに追記
$ vim settings.py

settings.py

INSTALLED_APPS = (
..
    'celerytest',
)
task実行してみる
$ python manage.py shell
>>> from celerytest.tasks import add
>>> result = add.delay(2, 2)
>>> result
<AsyncResult: 08af09fa-1d18-4891-86dd-17b18d323225>
>>> result.result
4
>>> result.successful()
True

キュー実行されてる

Djangoの管理画面からタスク状況見る

celerycam を起動させとくとsnapshotを保存してくれて、adminで閲覧できるようになる
https://groups.google.com/group/celery-users/browse_thread/thread/5e9a12f595ae5f67

$ python manage.py celeryd -E --loglevel=DEBUG
$ python manage.py celerycam --loglevel=DEBUG

adminのdjcelery -> Tasks に表示される
celeryd を -E で起動しておかないと記録されないので注意

Unit Test

このままだと、python manage.py test したときにもCelery にタスクが投げられてテストが通らなくなったりする

そんなときは settings.py に以下の設定を追加ればいい

CELERY_ALWAYS_EAGER = True

http://ask.github.com/django-celery/cookbook/unit-testing.html

どうやら

いろいろ設定オプションやらなんやらある模様

Brokerをredisにするとdata lostの可能性があるよ的なことが書いてあったけど
とりあえず何も考えなくてよかったのでとっかかりredisにしてみました

celery的にはとりあえずrabbitmq使っとけ、って感じらしいけど

http://celery.readthedocs.org/en/latest/getting-started/first-steps-with-celery.html#choosing-your-broker


そのへんのことはいろいろおいおいしらべてく

South を使い出したら <app>/fixtures/ 以下を読み込んでくれなくなった

http://south.aeracode.org/docs/settings.html#south-tests-migrate

設定値を変えればいいらしい

settings_test.py

SOUTH_TESTS_MIGRATE = False

test 時に migrate をする必要はないので False にしておく

setteingsを指定してテスト実行

$ python manage.py test <app> --settings=settings_test

ちなみに環境は

  • Django 1.4
  • South 0.7.4

pip で PIL が入らなかった

pythonbrew venv create した 仮想環境で PIL がうまくインストールできてなかった
必要なライブラリはインストール済みのはずなのに、not available になる

環境は CentOS 6.2

$ pybrew venv create hoge
$ pip install PIL
..
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version       1.1.7
platform      linux2 2.7.2 (default, May  7 2012, 15:19:14)
              [GCC 4.4.6 20110731 (Red Hat 4.4.6-3)]
--------------------------------------------------------------------
*** TKINTER support not available
*** JPEG support not available
*** ZLIB (PNG/ZIP) support not available
*** FREETYPE2 support not available
*** LITTLECMS support not available
-----------------
..

PATH 関連がうまくいってないっぽいけど、とりあえずシンボリックリンク作ったらできた

$ sudo su -
# ln -s /usr/lib64/libz.so /usr/lib/
# ln -s /usr/lib64/libfreetype.so /usr/lib/
# ln -s /usr/lib64/libjpeg.so /usr/lib/
$ pip install PIL
..
PIL 1.1.7 SETUP SUMMARY
--------------------------------------------------------------------
version       1.1.7
platform      linux2 2.7.2 (default, May  7 2012, 15:19:14)
              [GCC 4.4.6 20110731 (Red Hat 4.4.6-3)]
--------------------------------------------------------------------
*** TKINTER support not available
--- JPEG support available
--- ZLIB (PNG/ZIP) support available
--- FREETYPE2 support available
*** LITTLECMS support not available
..

なんか

他にちゃんとした方法ないすかね…