JaikuEngineをインストールする
基本的には上記サイトの手順通りにします。
ただ、GAEはあれから仕様がどんどん変わり、JaikuEngineはオープンソースとはいえ長いことメンテナンスされていません。そのままでは動かないです。
直したところ
appengine_django/__init__.py の212行目あたりをこんな感じに。
-appconfig, unused_matcher = dev_appserver.LoadAppConfig(PARENT_DIR, {}) +appconfig, unused_matcher, from_cache = dev_appserver.LoadAppConfig(PARENT_DIR, {})
あと .google_appengine はディレクトリごと削除。
ドメインに"-"(ハイフン)とか使ってる場合はアバターアイコンがアップロードできないので、
common/validate.py の21行目をこんな感じに。
-AVATAR_PARTIAL_PATH_RE = r'(default|(?P<nick>#?\w+@[\w\.]+))/(?P<path>.*)' +AVATAR_PARTIAL_PATH_RE = r'(default|(?P<nick>#?\w+@[\w\.-]+))/(?P<path>.*)'
現状はとりあえずこれで何とか動いています。
cloudControlで.htpasswdの設定とphpMyAdminのインストール
無料で使えるらしいPHPのPaas、cloudControlのアカウントを作ってみました。
参考:PHPのPaaSを提供する「cloudControl」と「PHP Fog」 − Publickey
Tutorialに従ってあれこれ設定すればとりあえずデプロイまではいけます。Bazaarとか初めて使うよ。
MySQLのaddonの追加の仕方まで載ってるので親切。データベース苦手なヘタレなのでとりあえずphpMyAdminを入れてみようと思いました。
まずphpMyAdminでごにょごにょしたり、phpinfoを表示するためのディレクトリを掘って、.htaccessと.htpasswdを置いてパスワード制限を掛けようと考えてやり方をググってみました。
.htaccess:
AuthUserFile /data/local//current/<作業ディレクトリ>/.htpasswd AuthGroupFile /dev/null AuthName "Please enter username and password" AuthType Basic require valid-user
このAuthUserFileのパスはgetcwdを表示するだけのPHPファイルをアップして調べました。ルートは /data/local/
作業ディレクトリにphpinfoを表示するだけのPHPファイルをアップして眺めてみます。PHPのVersionは5.3.2、mysqlが有効になっています。GDも使える。素敵!
作業ディレクトリにphpMyAdminのディレクトリを掘ってconfig.inc.phpを設定します。ここで気をつける必要があって、TutorialにもあったようにMySQLの各種パラメータは以下のような感じになっています。
Addon : mysql.free Settings mysql_password : w12XYabcdefg3uHG mysql_hostname : 127.0.0.1 mysql_user : dep12ab34xyz mysql_database : dep12ab34xyz mysql_dbsize : 5
config.inc.phpの$cfg['Servers'][$i]['host']にはデフォルトで'localhost'って書いてますが'127.0.0.1'に直さないといけないんですね。ここで少しハマりました。
$cfg['Servers'][$i]['host'] = '127.0.0.1';
これでデプロイして、めでたくphpMyAdminにログインできました。他所のサーバでPHPで動かしていたTwitterBotとかをこっちに移植できたらな、と考えていますが、今日はここまで。
Eclipse3.6(Helios)に乗り換え
Eclipse3.5(Galileo)でPHP,JavaScript,Ruby,Python,Perlの開発環境構築っていうのを昔やったので、Eclipse3.6でも同じようにやってみたら問題なく移行できました。
今回は気分を変えて英語のままで、あとEclipse Classicをベースに後からPDTをインストールしてみました。
PDTを"Install New Software..."からインストールするときのURLは http://download.eclipse.org/tools/pdt/updates/2.2/milestones です。
RadRailsはRubyとあわせてRailsごとインストールしたけど問題なく動いてますね。昔やったときは競合して動かなくなったのでRailsは外しましたが今回は問題なさそうです。これを機にRails覚えてみようかな…。いや、その前にJavaか…。
参考にさせて頂いたサイト様
Google App Engineで画像処理するためにpypngを使ってみた
Google App Engineで画像処理をしようと思ったのですが、公式で提供されているAPIは機能が少なすぎます。
http://code.google.com/intl/ja/appengine/docs/python/images/
Pythonの画像処理で有名なライブラリにPIL(Python Imaging Library)というのがあるらしいのですがGoogle App Engineでは使えないそうです。
http://www.pythonware.com/products/pil/
そこでPure Pythonのライブラリであるpypngを使うことにしました。
GIFが対象の場合はpygifで頑張ってる方がいらっしゃったのでリンクを張っておきます。
- http://d.hatena.ne.jp/miz999/20110218/1298056217
- http://d.hatena.ne.jp/miz999/20110226/1298720099
- http://d.hatena.ne.jp/miz999/20110304/1299254436
やりたいこと
PNGの左上(x,y)=(0,0)のドットと同じ色を透過色にする
PHPでGDを使えばこれだけで済むんだけど…
https://gist.github.com/824781
今までは外部サーバにこれを設置して処理を丸投げしていたのですが、諸事情で使えなくなりそうなので、頑張ってpypngでやります。
pypng
Google Code
http://code.google.com/p/pypng/
Document
http://packages.python.org/pypng/
説明がシンプルすぎます。
詳細な使い方を知るにはソース読むしかないです…。
とりあえず読み込む
read()でもいいのですがasRGB8()っていうメソッドを見つけたのでこれを使います。
8bitPNGとして読み込んで統一しておいたほうが書き込む時にRGBAの範囲を0-255に決め打ちできて後々楽だと考えました。
GAEのことは忘れてファイルの読み書きをしますよ。
import png pr = png.Reader(file=open('before.png', 'rb')) x,y,pixels,meta = pr.asRGB8() print x,y,pixels,meta
16 16{'bitdepth': 8, 'colormap': False, 'interlace': 0, 'planes': 3, 'greyscale': False, 'alpha': False, 'size': (16, 16)}
x,y,metaの型はわかった。generator objectってなんぞ?(・ω・`)
http://www.panopticon.jp/blog/2007/02/152332.html
なるほど。for文で回せるオブジェクトを関数みたいに定義して作成したもの、という理解であってるかな?
ピクセル全部を配列に入れて保持してるとメモリが大変でしょ、っていう配慮だろうか?
"イテレータ"っていうのを知るともっと賢くなれそうなので後で調べてみる。
http://jutememo.blogspot.com/2008/06/python.html
とりあえずforで回してみた
for p in pixels: print p
[125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55] [125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55] [125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 56, 125, 82, 58, 125, 82, 58, 125, 82, 57, 125, 81, 55, 125, 81, 55] [125, 81, 55, 125, 81, 55, 125, 81, 56, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 82, 56, 125, 80, 52, 125, 73, 41, 125, 74, 42, 125, 76, 45, 125, 82, 57, 125, 81, 55] [125, 81, 55, 125, 82, 57, 125, 79, 51, 125, 80, 53, 125, 82, 57, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 82, 56, 125, 79, 50, 125, 86, 65, 127, 126, 142, 128, 134, 153, 126, 107, 105, 125, 77, 46, 125, 82, 56] [125, 81, 56, 125, 76, 46, 125, 88, 69, 125, 85, 63, 125, 77, 47, 125, 82, 56, 125, 81, 55, 125, 81, 55, 125, 81, 54, 125, 82, 59, 129, 154, 195, 127, 124, 138, 126, 101, 90, 129, 155, 197, 127, 117, 124, 125, 74, 43] [125, 76, 46, 127, 119, 128, 128, 142, 173, 129, 144, 177, 126, 106, 104, 125, 77, 46, 125, 82, 57, 125, 82, 58, 125, 74, 41, 127, 118, 125, 129, 149, 186, 124, 68, 31, 125, 71, 36, 126, 99, 90, 129, 160, 206, 125, 78, 49] [126, 90, 73, 129, 158, 202, 125, 80, 53, 126, 98, 87, 129, 155, 197, 125, 79, 51, 125, 81, 55, 125, 83, 58, 125, 72, 38, 128, 130, 150, 128, 136, 160, 125, 74, 42, 125, 83, 59, 125, 90, 72, 129, 161, 207, 125, 84, 62] [126, 98, 87, 129, 153, 194, 125, 69, 32, 125, 84, 62, 129, 157, 199, 125, 83, 59, 125, 80, 54, 125, 83, 58, 125, 74, 42, 127, 115, 119, 129, 152, 191, 125, 69, 32, 124, 69, 32, 126, 103, 98, 129, 158, 204, 125, 77, 47] [125, 80, 52, 128, 146, 180, 127, 120, 132, 128, 134, 156, 128, 133, 155, 125, 75, 43, 125, 81, 55, 125, 80, 53, 125, 80, 53, 125, 80, 54, 129, 150, 187, 128, 131, 152, 127, 108, 106, 129, 158, 202, 127, 111, 113, 125, 75, 44] [125, 79, 51, 125, 84, 62, 127, 119, 129, 127, 114, 118, 125, 76, 46, 126, 102, 97, 128, 139, 162, 128, 137, 160, 127, 127, 142, 125, 80, 53, 125, 82, 58, 127, 120, 131, 128, 128, 145, 126, 99, 91, 125, 76, 46, 125, 82, 56] [125, 81, 56, 125, 80, 53, 125, 74, 41, 125, 75, 43, 125, 81, 54, 125, 84, 60, 125, 87, 67, 125, 87, 67, 125, 86, 64, 125, 81, 56, 125, 80, 54, 125, 74, 41, 125, 73, 40, 125, 77, 47, 125, 82, 57, 125, 81, 55] [125, 81, 55, 125, 81, 56, 125, 82, 58, 125, 82, 57, 125, 81, 55, 125, 80, 54, 125, 79, 52, 125, 79, 52, 125, 80, 53, 125, 81, 55, 125, 81, 56, 125, 82, 58, 125, 83, 58, 125, 82, 57, 125, 81, 55, 125, 81, 55] [125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55] [125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55] [125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55, 125, 81, 55]
3つずつのペアになっていて、左から順にRGB値になってるっぽいですね。
用意した画像が16x16なので16x16個、ちゃんとあります。
とりあえず書き込む
何も加工せずそのまま書き込めば画像のコピーができるはず。
pw = png.Writer( x, y, interlace=False, bitdepth=meta['bitdepth'], planes=meta['planes'], alpha=False ) pw.write(open('after.png', 'wb'), pixels)
本題
透過するには書き込み時にalpha=Trueとすれば良いわけですが、3つずつのペアになっていたピクセルのデータを4つのペアにする必要があります。
4つ目がアルファ値ですね。0が透過、255が透過無し、のようです。
左上のドットのRGB[r,g,b]を覚えておいてそれに一致するドットは[0,0,0,0]とかにしたいわけです。
それ以外は[r,g,b,255]にすれば元のままです。
import png pr = png.Reader(file=open('before.png', 'rb')) x,y,pixels,meta = pr.asRGB8() new_pixels = [] i = -1 for ps in pixels: if i == -1: r = ps[0] g = ps[1] b = ps[2] i = 0 new_p = [] new_p_set = [] for p in ps: new_p_set.append(p) i += 1 if i >= 3: new_p_set.append(255) if new_p_set == [r, g, b, 255]: new_p_set = [0, 0, 0, 0] new_p.extend(new_p_set) i = 0 new_p_set = [] new_pixels.append(new_p) pw = png.Writer( x, y, interlace=False, bitdepth=meta['bitdepth'], planes=meta['planes'], alpha=True ) pw.write(open('after.png', 'wb'), new_pixels)
な、なんかPythonなのに汚いな!でも動いたからよし!
ところでwriteするときにリスト渡しちゃってるけどせっかくreadでgenerator返ってきてるのに意味なくね?
generatorにして引数に渡しましょう。勉強にもなるし。
import png pr = png.Reader(file=open('before.png', 'rb')) x,y,pixels,meta = pr.asRGB8() def new_pixels(pixels): i = -1 for ps in pixels: if i == -1: r = ps[0] g = ps[1] b = ps[2] i = 0 new_p = [] new_p_set = [] for p in ps: new_p_set.append(p) i += 1 if i >= 3: new_p_set.append(255) if new_p_set == [r, g, b, 255]: new_p_set = [0, 0, 0, 0] new_p.extend(new_p_set) i = 0 new_p_set = [] yield new_p pw = png.Writer( x, y, interlace=False, bitdepth=meta['bitdepth'], planes=meta['planes'], alpha=True ) pw.write(open('after.png', 'wb'), new_pixels(pixels))
できました。
ここでGAEのことを思い出します。
GAEはファイルの読み書きができないのでStringIOを使うのが定石らしいです。
from StringIO import StringIO import png #前略 pr = png.Reader(file=StringIO(image_binary_data)) #中略 o = StringIO() pw.write(o, new_pixels(pixels)) new_image_binary_data = o.getvalue() #後略
こんな感じで変換後のバイナリデータを取り出せます。
画像処理って難しいですね!
Google App Engine/PythonではてなOAuth
AppEngine-OAuth-Libraryを拡張
はてなハイクでOAuthがサポートされたので、Google App Engine/Pythonから利用しようと思ったのですが、
Twitterでも実績のあるAppEngine-OAuth-Libraryが全然動きませんでした。
厳密な仕様に準拠していないっぽいです。なので、はてなでも動くように修正してみました。
以下から入手できます。
https://github.com/nikolat/AppEngine-OAuth-Library
注意点
はてなで利用する際はアクセストークン取得時にscopeパラメータを指定しないといけません。
以下のように第四引数に指定してください。コールバックURLは必須です。
import oauth CONSUMER_KEY = 'xxxx' CONSUMER_SECRET = 'xxxx' CALLBACK_URL = 'xxxx' SCOPE = 'read_public,write_public' client = oauth.HatenaClient(CONSUMER_KEY, CONSUMER_SECRET, CALLBACK_URL, scope=SCOPE) redirect_url = client.get_authorization_url()
Eclipse3.5(Galileo)でPHP,JavaScript,Ruby,Python,Perlの開発環境構築
Eclipse 3.4(Ganymede)からの移行
今までLLはEclipse 3.4に各種プラグインを入れて書いていたのですが、Eclipse 3.5を試してみたくなったので、その過程を記録しておきます。
環境はWindows Vista 32bitです。
Apache 2.2, PHP 5.2.9, Ruby 1.8.7, RubyGems 1.3.4, Python 2.5.2, Perl 5.10.0 がインストール済です(Program Filesの中にインストールするのはやめた方がいいと思います)。
Eclipse 3.5のダウンロード
Enabling Open Innovation & Collaboration | The Eclipse Foundationの右上のDownload Eclipseに進みます。
Eclipse for PHP DevelopersのWindows 32bitを選択します。
(Eclipse ClassicからPDTを入れようとすると苦労するのでやめた方がいいです)
ダウンロードを開始します。
適当なディレクトリに展開してインストールが完了します。
日本語化
Ecipseを起動する前にさっさと日本語化してしまいます(必要ない場合はすっとばして構いません)。
Eclipse 日本語化 | MergeDoc Projectから日本語化のプラグインをダウンロードします。
「最新版」と書かれたリンクに進みます。
「Links to HEAD」の「download」からダウンロードを開始します。
適当なディレクトリに展開し、中にある「plugins」「features」の2つのフォルダをEcipseのディレクトリにコピーして統合します。
eclipse.iniの最後に「-javaagent:plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar」の一行を追加して完成です。
eclipse.exeをダブルクリックすると日本語化された状態で起動します。
eclipse.exe -clean.cmdというファイルもeclipseのディレクトリにコピーしておいたほうが良いです。後で何度も使います。
Eclipseの設定
このへんはお好みで。「ウィンドウ」>「設定」>「一般」>「ワークスペース」で「テキスト・ファイル・エンコード」を「UTF-8」に。
あとは「一般」>「エディター」>「テキストエディター」で「行番号の表示」をONに、「一般」>「外観」>「色とフォント」>「基本」>「テキスト・フォント」で「MS ゴシック」サイズを「9」に、など。
PHPの設定
Xdebug: DownloadsからXdebug 2.0.5の5.2 VC6 (32 bit)をダウンロードしてきます(今回のPHPのバージョンが5.2なので)。そしてPHPのインストールされたディレクトリ内のextフォルダにコピーして、php.iniに以下の記述を加えます。
(PHP 5.3の場合は"zend_extension_ts"でなく"zend_extension"と書きます)
[xdebug] zend_extension_ts="C:\****\ext\php_xdebug-2.0.5-5.2.dll" xdebug.remote_enable=1 xdebug.remote_handler="dbgp" xdebug.remote_mode=req xdebug.remote_host="localhost" xdebug.remote_port=9000 xdebug.remote_log="C:\****\logs\xdebug.log" xdebug.manual_url = http://jp2.php.net xdebug.collect_params = On xdebug.dump.GET = * xdebug.dump.POST = *
xdebug.remote_logにはApacheのlogsフォルダ内を指定しておきます。
Apacheが起動している場合は再起動してください。
Eclipseに戻って、「ウィンドウ」>「設定」>「PHP」>「PHP実行ファイル」で以下のような感じで追加します。
「PHP」>「デバッグ」でPHPデバッガーにXDebugを指定しておきます。
これでPHPの設定は完成です。適当なプロジェクトを作成して実行してみます。
ブレークポイントを置いてデバッグの動作確認もしておきます。
無事に動きました。
Aptanaの設定
JavaScriptやHTML、CSSコーディングのためにAptana Studioのプラグインをインストールします。
「ヘルプ」>「新規ソフトウェアのインストール」で http://download.aptana.org/tools/studio/plugin/install/studio を追加します。
ナビゲーションに従ってインストールが完了したら、一度Eclipseを終了し、-cleanオプション付きで起動し直します(eclipse.exe -clean.cmdをコピーしていた場合はそれをダブルクリックするだけで良いです)。
起動したら「ウィンドウ」>「設定」>「Aptana」>「Startup Page」で始動後に表示しないにチェック。
パースペクティブを切り替えてプロジェクトを作ってみます。
JavaScriptライブラリーのインポートについて訪ねられますので必要ならインストールしておきます。
今回はとりあえずjQuery 1.3.2だけにしておきます。
インストールが終わったらEclipseを終了し、-cleanオプション付きで起動します。
再びプロジェクトの作成からやり直します。今度はjQueryが選択出来るようになっています。
jQueryのサンプルを含んだプロジェクトができました。
今後.jsファイルはAptana JS エディターで編集したいので、「ウィンドウ」>「設定」>「一般」>「エディター」>「ファイルの関連付け」で.jsファイルをAptana JS エディターに関連付けておきます。
Rubyの設定
「ヘルプ」>「新規ソフトウェアのインストール」で http://download.aptana.com/tools/radrails/plugin/install/radrails-bundle を追加します。
「項目をカテゴリー別にグループ化」のチェックを外し、「Ruby 開発ツール」のみを選択します。
インストールが完了したらEclipseを終了して-cleanオプション付きで起動します。
少し経つとgemの自動インストール画面が開きます。必要なモジュールをgemで勝手にインストールしてくれます(初めて利用する場合はもっとたくさんのモジュールが表示されるはずです)。
必要なgemのインストールが終わったら「ウィンドウ」>「設定」>「Ruby」以下、必要なパスを入力していきます。
設定が完了したら、適当なプロジェクトを作成して実行してみます。
デバッグの動作確認もしてみます。
ruby-debug-ideが古いっぽいです。さっき自動でインストールされた方は問題ないですが私の場合は自分でアップデートする必要がありそうです。
しかし >gem install ruby-debug-ide とか打ってもエラーが出てインストールに失敗してしまいます。色々ググったところ、ruby\lib\ruby\1.8\i386-mswin32\config.hの一行目を以下のように書き換えて、ruby-debug-baseからインストールすると良いとのこと。
修正前
#if _MSC_VER != 1200 #error MSC version unmatch: _MSC_VER: 1200 is expected.
Pythonの設定
「ヘルプ」>「新規ソフトウェアのインストール」で http://pydev.org/updates を追加します。
PyDevの方にチェックを入れてインストールします。
インストールが完了したらEclipseを終了して-cleanオプション付きで起動します。
起動したら「ウィンドウ」>「設定」>「Pydev」>「インタープリター - Python」で新規にPythonのパスを指定。
パースペクティブを切り替えて、適当なプロジェクトを作成して実行してみます。
デバッグの動作確認もしてみます。
コンソールに何かwarningが出てますがまあいいでしょう。
Perlの設定
「ヘルプ」>「新規ソフトウェアのインストール」で http://e-p-i-c.sourceforge.net/updates/ を追加します。
EPICにチェックを入れてインストールします。
インストールが完了したらEclipseを終了して-cleanオプション付きで起動します。
起動したら「ウィンドウ」>「設定」>「Perl EPIC」でPerl 実行ファイルのパスを指定。
パースペクティブを切り替えて、適当なプロジェクトを作成して実行してみます。
デバッグの動作確認もしてみます。
無事に動きました。
参考にさせて頂いたサイト様
- http://modern-magic.net/blog/2009/12/xmapp-eclipse-pdt-xdebug%E3%81%A7%E5%BF%AB%E9%81%A9%E3%81%AAphp%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83%E3%82%92%E4%BD%9C%E3%82%8B/
- Ruby、Rails開発環境構築 Eclipse3.5 + Aptana Studio2.0 + RadRails 2.0 日本語化 - WEBぷろぐらま〜 システム開発エトセトラ
- NetBeans6.8でFastDebuggerがインストールできない | 超ド素人のRuby on Rails挑戦日記
- Eclipse で PyDev を使う - えこ日記
- EclipseでPerlをやる(EPIC) - guri_2::perlメモ - Hatena::Group::Perl