daemonfreaks.com

Python3系に移行した

posted by jun-g at Sun, 21 Jun 2020 11:51 JST

このブログは未だにPyBlosxomで運用しているわけですが、Python2系の公式サポートもそろそろ終了とのことなので、ここのPyBlosxomもPython3系に移行しました。

詳細は別途書きますが、まだpluginに細かいバグが残ってるのと、実行環境に調整の余地ありなので、チマチマ改善していきます。

取り急ぎ。

PyCon JP 2014 に参加してきた その2

posted by jun-g at Wed, 17 Sep 2014 02:08 JST

引き続き PyCon JP 2014 の9/14の各セッションの感想。

/images/blog/pycon2014-0914-01.jpg

基調講演

西尾さんによる基調講演。

「再発見」についてのくだりで出てきた「盲点」についての説明、ぼんやりと感覚的に理解してたけどはっきりとした言葉で説明を聞いてなんだかとても感心しました。

常に盲点があるんじゃないか?と疑う気持ちを忘れないようにしたいですね。

Job Fair

/images/blog/pycon2014-0914-02.jpg

「GitHubとかJIRAとかHipChat/Slackを使ってコミュニケーション取りながら開発してます」とか「でも結局最後はツールじゃなくて人間系だ」とか。

大体どこも同じですねぇ…。

ランチタイム

同僚と合流できたのでぼっち飯は回避。

OpenCVのpythonインターフェース入門

途中で仕事の電話がかかってきてほとんど聞くことが出来ませんでした…。

Pythonによる非同期プログラミング入門

Python3.4から asyncio という非同期系のライブラリが標準で同梱されるようになったそう。

これ、2系にもバックポートされないですかね。

Python + Hive on AWS EMR で貧者のログ集計

やっぱみんな fluentd 使ってるんだな〜って思いました。

パッケージングの今

distributesetuptools が合流したのでそのまま気にせず setuptools を使っていたのですが、どうやら pip の方が本流のようですね。恥ずい。

あと wheel というライブラリを使えばC拡張などのコンパイル済みバイナリもパッケージに含められるそう。

正規表現リテラルは本当に必要なのか?

re.compile()を実行しなくても実は内部でコンパイル済みオブジェクトがキャッシュされているというのは初めて知りました。

個人的には正規表現リテラルがなくても困ってないです。

Lightning Talk

銅鑼がすごかった。(2回目)

closing

抽選会だったが飛行機の時間に間に合わなくなりそうだったので、残念ながら途中で離脱しました。残念。

まとめ

とても楽しく過ごせた2日間でした。やっぱこういった場所に定期的に出かけて刺激を受けないとダメですね。

講演者およびスタッフの皆様、ありがとうございました。

また来年。

/images/blog/pycon2014-0914-03.jpg

PyCon JP 2014 に参加してきた その1

posted by jun-g at Mon, 15 Sep 2014 22:05 JST

9/13〜14の2日間、東京で開催された PyCon JP 2014 に参加してきました。

こういったイベントに参加するのは約3年ぶりでして、仕事も最近はもっぱらマネージャー業と業務べったりな泥臭い作業ばかりで正直エンジニアとしては死に体な状態だったのですが、久しぶりにエンジニアとしてワクワクする気持ちみたいなものを思い出して2日間楽しく過ごさせていただきました。

終わり。

…という全体の感想だけだと面白くないので、見た講演・セッションの感想をざっと。

基調講演

/images/blog/pycon2014-0913-01.jpg

Python2ユーザーがPython3にほとんど移行してなくて、Python3のユーザーはほとんどが新しいPythonユーザーで旧来の2系ユーザーと新参の3系ユーザーでコミュニティの分断が起きている、みんな恐れずに実際に3を使ってみてフィードバックしてよ、というお話。

講演者の「でも個人的には2系の方が好きだよ3系に移行するベネフィットは無いよ」といったニュアンスの発言だけが強調して拡散されてしまってネット上で物議を醸しているようですが、まぁそれは別の話。

業務で使ってる部分は3系に移行するコストがでかすぎて現実的ではない、と思いつつも、だからって何もしないわけにもいかないので、プライベートで書いたプログラムをちょっとずつ3系に移行して知見を溜めるということを個人的にやってます。

質疑応答で3系の良い部分を2系にバックポートして新たなバージョンを作るのはどうか?といった意見も出たのですが、そういう未来もいいと思いました。

Deep Learning for Image Recognition in Python

/images/blog/pycon2014-0913-02.jpg

今年のPyConJPは全体的に機械学習や統計系のセッションがたくさんあって「うーん数学系とか学術系は苦手だ」と思って身構えていたのですが何となく自分の守備範囲に無いお話を聞いて新たな刺激をもらおう、と思ってこのセッションに参加しました。

が…心配とは裏腹に、このセッションはむちゃくちゃ面白かったです。

Deep Learning(深層学習)という言葉は初めて聞いたのですが、ニューラルネットワークというのは以前少し聞いたことがあったので、内容は何となく理解できました。

何よりも、理屈を完全に理解してなくても頭の良い人たちが作ったものを使って比較的手軽に高度なことができる、という恵まれた時代に生きていることを改めて認識できたことが良かったです。

ちょっと思いついた仕事上のアイディアもあるので今度試してみようと思います。

The esperanto generator

発表者は中学1年生。若い…。

オトナでは到底不可能な発想で、高度なテクノロジーをまるでおもちゃのように扱うその発想力と行動力に度胆を抜かれました。

実はコードをまだ1行も書いてません!とかそんなのはまったく問題じゃなかった。(実業務だったらどつくけどね。)

ランチタイム

安定のぼっち飯でスムーズにクリア。

オライリーのブースで Python文法詳解 の先行販売および(トイプー使いで有名な)著者のサイン会が行われていたのと、特典がいろいろあったので特典が全部もらえるまで大人買いしてサインも頂いておきました。(特典はトートバックとTシャツとカードゲームとボールペンでした。)

/images/blog/pycon2014-0913-04.jpg

むしろこれが今回の本当の目的だったのです。欲しい本をフラゲして著者にサインをもらう。この行為を会社の出張として処理する。素晴らしい。

Pythonの実装系総ざらい

いわゆるCPythonとかJythonとかIronPythonのお話。

Dropbox社で開発している Pyston という新しい実装の説明があり、計測すると再帰はPyPyより速いがループはCPythonより遅いとのことでした。これからが楽しみなプロジェクトですね。

最新リリースCMSツール Plone 5 のモダンUIとテクノロジーの進化

Plone、生きていたのか…。という感想でした。(失礼)

職場ではかろうじてPlone3/Zope2が動いているサーバーが1つだけ残ってて、もうすぐ息の根を止める予定になってます。

XML-RPC : Pythonが「電池付属」と呼ばれる理由

まさか2014年に改めてXML-RPCの説明を聞くことになるとは思ってもみませんでした。

でも今年のPyConJPのテーマは「Pythonで再発見」だからむしろドンピシャなテーマでしたね。

サーバー・クライアント両方のライブラリが揃っててとてもお手軽に使えるので、APIの基盤も何もないような状況でHTTPで連携する必要があるシーンなんかだと、今でも十分に使えるのではないかと思いました。

そんなシーンがあるのか不明。

リファクタリングツールあれこれ

/images/blog/pycon2014-0913-03.jpg

標準の規約に従ってコード書いてるなら自動的にチェックするライブラリがある程度揃ってるから楽しようぜというお話。

標準の規約に従ってコード書いてるなら、ね。(意味深)

Python を支える技術: ディスクリプタ編

個人的にかなり興味がある部分、のはずなんですが、意識飛びました。すみません…。

朝4時半起きだったので疲れてたんだ。

Python文法詳解 に同様の説明が書かれているようなので、あとで読む。

Lighthning Talk

銅鑼がすごかった。

nakagamiさん の発表が良かった。いつもブログを拝読させていただいているが、何となくガツガツしてない感じがとても好感が持てる。

Party

カンファレンス終了後に立食パーティーがあったのですがコミュ障がそんなところに長居できるはずもなく、乾杯の後早々に退散して、東京在住の兄と月島で待ち合わせしてもんじゃ焼きを食べに行きました。

初めてもんじゃ焼きを食べましたがとても美味しかったです。ていうか粉モンがまずいわけがない。

そのあと体調が悪くなってフラフラでホテルに戻ってゲロ吐いて意識が途絶えて1日目終了(ひどい)。


酔っ払ってきたので(日常)、続き(14日分)のレポートは後日。

生きていた mod_python

posted by jun-g at Mon, 21 Oct 2013 00:26 JST

開発終了したはずの mod_python プロジェクトが復活してました。素晴らしい!

Python2.7、Apache2.4に正式に対応。あと、WSGI Handlerってのが増えてるみたいです。

未だにmod_pythonで動いてる弊社フレームワークは延命できそうで一安心。次の心配はPython2系の終わりかな?

雨なので

posted by jun-g at Sun, 20 Oct 2013 15:09 JST

先日作ったアプリ のコードを整理して、リポジトリを bitbucket に移動。

いちいちUSBでPCに接続して、ファイル名をkepubにリネームしてからコピーして、という手順がなくなっただけで随分楽になりました。

zipをcbz、rarをcbrに変換するのも簡単にできますね。後で追加しよう。

PyCon mini JP に参加してきた

posted by jun-g at Sun, 30 Jan 2011 14:07 JST

PyCon mini JP

いやぁ、楽しかった。前日3時間しか寝てなくて当日居眠りしそうだなぁと思ってたけど、少し眠くなるぐらいでずっと楽しめた。大阪から行った甲斐があった。講演者、スタッフ、スポンサーの皆様、ありがとうございました。

今回Nexediの奥地さんによる「ERP5の紹介」という講演を一番楽しみにしていたけど、キャンセルになってしまって残念だった。しかし、代わりの「テンプレートエンジンの高速化と失敗談について」という講演が結局一番面白く、為になった。これは、自分がテンプレートエンジンの開発経験があることと、高速化をしたことがあるからだと思う。講演を聴きながら「あーそうそう」とか「へぇ!そうなのか!」とか色々思う事があって楽しかった。

次回また夏頃やれたらいいねというお話があったので、その際はまた参加したいと思う。どうかチャリイベントの日と被りませんように!

Xperia (Android2.1) の隠しアプリをSL4Aから起動

posted by jun-g at Sun, 05 Dec 2010 11:54 JST

XperiaのOSがAndroid2.1になったらSL4AのPythonがまともに動作するようになってちょっと嬉しい。

さて、2.1になったXperiaには3D ギャラリーとオーディオプレイヤーが隠れているようで、リンク先ではADWランチャーを使う方法が紹介されているけど、他にもマーケットからショートカットアプリをインストールする等の方法があるみたい。

で、隠れてるってことはSL4Aから直接起動させれば良いだけなんじゃないの〜?と思ったので試してみた。

オーディオプレーヤー。

import android
droid = android.Android()
droid.launch("com.android.music.MediaPlaybackActivityStarter")

3Dギャラリー。

droid.launch("com.cooliris.media.Gallery")

どっちもテンプレに1行足しただけ。苦労した点はアプリのクラス名探し当てるのと、実機の画面から文字入力した事の2点。

そういえばAndroid2.1になって同期アカウントにlast.fmを追加することができるようになったのに、MediaScapeは未だにAudioScrobbleできないガッカリ仕様で残念。

梅py Python自習室

posted by jun-g at Sat, 08 May 2010 20:55 JST

参加してきた。ひたすら自習、というか溜まったTODOにちょっとずつ手をつける作業をした。flickrapiとかpyblosxom-1.5とかlibdrizzleとか。

久々に集中して作業できたので良かった。

梅.py Code Camp #1 in Kyoto

posted by jun-g at Sat, 03 Oct 2009 21:34 JST

10/23に梅.py Code Camp #1 in Kyotoが開催されます。お泊まり会同様に皆で集まって一晩どっぷり好きな事しようぜ、なイベントです。興味のある方は奮ってご参加下さい。

開催日時
2009/10/23(金) 15:00 ~ 24(土)11:00
場所
ヴィラージュ京都 (京都府京都市中京区壬生坊城町5)
定員
12人
参加方法
ATNDの「梅.py Code Camp #1 in Kyoto」からお申し込みください

ちと日程の都合が合わない為、残念ながら僕は参加出来ません…。手伝いも何もできなくて申し訳ないです…。

Python2.3でeucjp-msとかiso-2022-jp-msとか

posted by jun-g at Thu, 19 Feb 2009 02:48 JST

ふと思い立って、Legacy Encoding Projectで公開されているPython2.4向けのパッチをCJKCodecs 1.1.1用に修正してみました。

今時Python2.3以前のバージョンを使っている環境なんてほとんどないと思いますが、せっかくなのでダウンロード可能な場所に置いておきます。

cjkcodecs-1-1-1.patch

第1回 Python関西お泊まり会を開催しました

posted by jun-g at Sun, 08 Feb 2009 12:52 JST

2/6~7の1泊2日で、第1回 Python関西お泊まり会を開催しました。

場所は京都・大宮のヴィラージュ京都というホテルを利用しました。会議室等はありませんが、予約していた6人部屋2つのうち、片側の部屋が十分な広さだったので、参加者10名が1部屋に集まって作業する事ができました。もう片側の部屋は就寝部屋(通称・野戦病院)として利用しました。

第1回 Pythonお泊まり会
第1回 Pythonお泊まり会 posted by (C)jun-g

参加者は以下の10名(参加申込順)でした。

以下、個人的な感想など。

  • ホテルが新しくて綺麗で良かった。梅田から1時間程度、と交通の便も良い。また利用したい。
  • 皆さんが電源タップと有線LANのハブと無線ルータとLANケーブルを大量に持ち込んでくれたので、ネットワーク環境も非常(無駄?)に充実したものとなった。
  • 皆さんの集中力がすごかった。終始黙々と作業。つられてすごい集中できた。
  • whosaysniがすごい勢いでelapheを作っていた。本当にすごい勢いだった。
  • 僕は終始TwitterBotのtv_prog_kansaiの機能追加をしてた。かろうじてお泊まり会中に完成できたので良かった。導入したら内容についてのエントリ書く。
  • Mercurial本の持参率が高かった。

一応幹事だったので簡単に会計報告しておくと、

宿泊費
1泊2日(朝食付き)6人部屋x2 合計40,000円
夕食代
近所の串カツ居酒屋 合計25,000円
おやつ・飲み物代
合計2,500円

で、1人あたり約7,000円弱でした。

とても充実した2日間で非常に楽しかったです。ご参加頂いた皆様、ブログやTwitter等で宣伝して頂いた皆様、ありがとうございました。

次は温泉地あたりでやりたいですねー。

第5回 梅田Pythonごはんの新年会 参加者募集のお知らせ

posted by jun-g at Wed, 31 Dec 2008 10:14 JST

大晦日ですが、告知です。1月にまたごはん会を開催します。

第5回 梅田 Python ごはんの新年会 (梅.py : 梅田 Python ごはんの会)

開催日時
2009/01/20 (火) 19:00~
場所
もつ鍋 廬山
予算
もつ鍋コース 2,500円 + 飲み代(合計4,000円ぐらい?)
参加方法
ごはん会のページからお申し込み下さい。

今回はもつ鍋です。白みそのダシがかなり美味いと聞いているので今から楽しみです。

いつもPythonの話を殆どしないただの飲み会と化してますので、皆様お気軽にご参加下さい。

第1回 Python関西勉強会(おやつ会)終了!

posted by jun-g at Sat, 27 Dec 2008 15:28 JST

というわけで、色々至らない点がありましたが、なんとか終了しました。幹事のdai_yamashitaさん、トーカー及びお手伝い頂いた皆様、お疲れ様でした。ご来場頂いた皆様、ありがとうございました。

ごはん会同様のんびりまったりとした内容になるかなと予想していたのですが、意外にカッチリした内容の勉強会になったなぁ、と思いました。次はもうちょっとまったりしてもいいかもね。

以下、何気に気になった2点。

  • 新原さんのDjangoPHPのデモで、Django側のコードに
    import PHPSerializer
    みたいなのが書いてあって、中身がどんなんかちょっと気になりました。
  • 増田さんの発表のデモ中に出てきた「49から始まる商品のコード」っていうのはJANコードの事でした。後で思い出しました…すみません。

Python関西の今後の予定は、1月ごはん会、2月お泊まり会、3月2回目の勉強会(未定)となっています。皆様是非お気軽にご参加くださいませ。

第1回 Python関西勉強会(おやつ会)を開催します!

posted by jun-g at Sat, 13 Dec 2008 03:18 JST

Python関西でも遂に勉強会を開催します!

「おやつ会」と銘打っているとおり、おやつでも食べながらスピーカーの方のお話聞いたり、コード書いたり、おしゃべりしたりしましょう、という集まりです。

第1回 Python関西勉強会(おやつ会)

開催日時
2008/12/23(火) 13:30 〜 17:00
場所
大阪産業創造館 D会議室
参加費
300円です。おやつたっぷり用意します。飲み物もこちら側で用意します。
スピーカー(順不同/敬称略)
ymasuda(標準Django完全解説 著者)
shin1x1(CakePHPガイドブック 著者)
僕もちょっとだけ喋ります。

LTして頂ける方もまだまだ募集しています。話を聞きにくるだけでも全然OKですので、おやつ食べに行くかぁ~ぐらいの気持ちでお気軽にご参加下さい!

ご参加頂ける方は上記リンク先の告知ページの申し込みフォームよりエントリーしてください。

Python関西第1回お泊まり会

posted by jun-g at Sun, 30 Nov 2008 23:58 JST

参加者の募集を開始します~。

開催日
2009/2/6(金) ~ 7(土)
宿泊場所
ヴィラージュ京都
15時チェックイン、翌11時チェックアウトです。
費用
一人5,000円固定(朝食付き)

詳細は「第1回 Pythonお泊まり会 - Python関西 | Google グループ」をご確認下さい。

梅pyごはん会同様、程良くゆるい感じでやりたいなぁと思っているので、皆様是非ご参加下さい。

第4回梅田Pythonごはんの会

posted by jun-g at Wed, 26 Nov 2008 01:25 JST

第4回梅田Pythonごはんの会も無事終了~。幹事のid:mitszoお疲れ様でした。参加された皆様ありがとうございました。毎度の事ながら、子育ての話、ビジネスの話、技術の話、と、色々な話が聞けてとても楽しかったです。僕は隙を見て会社の宣伝ばっかりしてましたがw

Python関西では、12月に勉強会(のような何か)、1月に新年会(のようなごはん会)、2月に開発合宿(のようなお泊まり会)を予定しています。興味のある方は是非ご参加下さい!! ←宣伝

chumbyでasahi.comのニュースを表示するウィジェット

posted by jun-g at Tue, 04 Nov 2008 00:33 JST

先日chumbyを購入しまして、早速asahi.comのニュースを表示するウィジェットを作ってみました。

まだ日本語が表示できないようなので、CGI側でニューステキストから画像を生成し、Flash側でその画像を横スクロールで表示するようにしてみました。

まずはCGI側。gdを使ってテキストを画像化します。news.cgiという名前で保存して適当なサーバに置きましょう。crossdomain.xmlも忘れずに。

#!/usr/bin/env python
# coding: utf-8

from cStringIO import StringIO
import random
import sys
import urllib2
from xml.etree.ElementTree import ElementTree

import gd


FEED_URL = "http://rss.asahi.com/f/asahi_newsheadlines"
WIDTH = 320
HEIGHT = 240
FONT_SIZE = int(HEIGHT * 0.8)
FONT_NAME = "ipag.ttf"


def _get_news():
    f = urllib2.urlopen(FEED_URL)
    dom = ElementTree(file=f)
    f.close()
    news = list()
    titletag = "{http://purl.org/rss/1.0/}title"
    for item in dom.getiterator()[1:]:
        if item.tag == titletag:
            text = item.text
            if text.startswith(u"AD:"):
                continue
            news.append(item.text)
    return random.choice(news)


def main():
    news = _get_news()
    width = int(HEIGHT * len(news) * 1.07) + (WIDTH * 2)

    img = gd.image((width, HEIGHT))
    color_white = img.colorAllocate((255, 255, 255))
    color_black = img.colorAllocate((0, 0, 0))

    img.fill((0, 0), color_white)
    img.string_ttf(FONT_NAME, FONT_SIZE, 0,
        (WIDTH + 1, HEIGHT - int((HEIGHT - FONT_SIZE) / 2)),
        news.encode("euc-jp", "replace"), color_black)

    f = StringIO()
    img.writeJpeg(f, 20)
    f.seek(0)
    sys.stdout.write("Content-type: image/jpeg\n")
    sys.stdout.write("\n")
    sys.stdout.write(f.read())
    f.close()


if __name__ == '__main__':
    main()

次はActionScript。showNewsImage.asという名前で保存。適当なサンプルを見ながら勢いで書いたので変な事してるところがあるかも。ツッコミ歓迎。

class ShowNewsImage {

    private var mcName:String = "NewsImage";
    private var imageURL:String = "http://example.com/cgi-bin/news.cgi";
    private var displayWidth:Number = 320;
    private var intervalId:Number = 0;

    public function ShowNewsImage(mc:MovieClip) {
        loadImage(mc);
    }

    private function loadImage(mc:MovieClip) {
        mc.createEmptyMovieClip(mcName, mc.getNextHighestDepth());
        var mcl:MovieClipLoader = new MovieClipLoader();
        var listener:Object = new Object();
        var me:ShowNewsImage = this;
        listener.onLoadInit = function(lmc:MovieClip) {
            lmc._x = 0;
            lmc._y = 0;
            me.intervalId = setInterval(me, "onTick", 10);
        }
        mcl.addListener(listener);
        mcl.loadClip(imageURL, mc[mcName]);

    }

    private function onTick():Void {
        if (_root[mcName]._width + _root[mcName]._x - 5 < displayWidth) {
            clearInterval(intervalId);
            loadImage(_root);
            return
        }
        _root[mcName]._x += -5;

    }

    static function main() {
        var app:ShowNewsImage = new ShowNewsImage(_root);
    }

}

でもってコンパイル。MTASCを使用。

$ mtasc -swf showNewsImage.swf -main ./showNewsImage.as -header 320:240:12

swfが出来たらprofile.xmlを作って一緒にUSBメモリに入れ、chumbyに突っ込んでブート。

これですべて上手く行くと思ったんですが…以下の問題が。

  • PC上のブラウザで見るよりスクロールがかなり遅い
  • 画像が途中で切れる?

画像が切れる問題はFlashPlayerでも再現しました。swfdec-playerだと問題ないんですが…。

続きはまた来週。

第3回梅田Pythonごはんの会

posted by jun-g at Mon, 27 Oct 2008 00:56 JST

という訳で第3回も無事終了。参加された皆様、ありがとうございました。幹事の@kfuruhataもお疲れ様でした。相変わらずほとんどPythonと関係の無い話ばかりしてましたが楽しかったです。あと遅刻してすみませんでした…。

次回のごはん会の参加者募集も近日中に開始すると思います。開発合宿しようぜ的な話も出ているので、興味のある方は是非Python関西にご参加下さい。

第2回梅田Pythonごはんの会を開催しました & 第3回の参加者募集のお知らせ

posted by jun-g at Sat, 04 Oct 2008 23:51 JST

直前にTwitterで参加者を募集したりしつつ、9/27に第2回梅田Pythonごはんの会を開催しました。

今回も参加者の皆様から色々と楽しいお話が聞けて非常に楽しかったです。ちなみに今回は子育ての話と職場におけるシャア(アズナブル)の存在について、といった話などで盛り上がりました。

そして次回第3回が10/25に開催されます。とりあえず集まってごはんでも食べましょう、という感じでゆるくやっているので、なんとなく興味のある方は是非一緒にご飯を食べましょう!!

そして、ごはんの会の延長というか、定期的に集まりつつ勉強会なんかもやっていきたいね、ということでPython関西が発足しました。ごはんの会と合わせてこちらもよろしくお願いします~。

PythonでAMF

posted by jun-g at Mon, 14 Jul 2008 01:39 JST

PYthonでAMFを扱うためのライブラリにPyAMFというのがありまして、こいつにはDjangoやGAE、WSGI上で動作させる為のゲートウェイモジュールが含まれていて、サイトに掲載されているサンプルもそれらを利用したものになっているのですが、そもそもそういったフレームワークが使えない、WSGI準拠でもない既存の環境で使用するにはどうすれば良いのか今ひとつわからなかったので、ちょろっと調べて、サイトにあるHelloWorldを動作させる為のシンプルなCGIを書いてみました。

#!/usr/bin/env python
# coding: utf-8

import sys
import pyamf
import pyamf.remoting.gateway

def echo(value):
    return value

services = {"echo": echo}

base_gateway = pyamf.remoting.gateway.BaseGateway(services)
context = pyamf.get_context(pyamf.AMF0)
pyamf_request = pyamf.remoting.decode(sys.stdin.read(), context)
pyamf_response = pyamf.remoting.Envelope(pyamf_request.amfVersion,
                                         pyamf_request.clientType)

for name, message in pyamf_request:
    pyamf_response[name] = base_gateway.getProcessor(message)(message)

print "Content-type: %s\n" % pyamf.remoting.CONTENT_TYPE
print pyamf.remoting.encode(pyamf_response, context).getvalue()

とまあ、こんな感じで、リクエストデータをPythonオブジェクトに変換、処理結果をAMFに変換してレスポンス、とすれば良いみたいです。何者にも依存しない最小の処理が分かれば既存の環境への組み込み方も考え易くなりますね。

ちなみに、Flexを全然触っていないので、AMF3で新たに扱えるようになったオブジェクトがそれぞれどういったものなのか、さっぱりわかっていません…。まずい…。

あと、FreeBSD portsにPyAMFが存在しなかったので、作ってsend-prしておきました。ports/125573です。

そんなこんなで、今日もわさびむの更新は無しです。という言い訳を書きたかっただけなのでした。

Python Developers Camp 2008 Winter に参加してきた

posted by jun-g at Wed, 12 Mar 2008 02:00 JST

という事で、今年もデブキャンに参加してきたよ。

合宿の内容に関しては、カトキチさんの「Python Developers Camp 2008参加メモ」が半端なく良くまとまってるので、ここを見ると良いと思う。カトキチさんとは、2日目のUnitTestのセッションでペアを組ませて頂いたんやけど、勤勉で物腰の穏やかな愛社精神溢れる素敵な方やった。僕と同い歳なのに、この差は一体…。見習いたい。

僕は動画配信をしつつ、マイペースにPylonsのチュートリアルをやったり、自作のメール通知系のプログラムとかtv_prog_kansaiとかを全部habu上に移行したいなーと思いながらhabuのソースを読んだりしてた。そういえばhabuの作者のlirisさんも参加されていたのに、緊張しすぎて話かけることができず…。jun-gはダメな子。

その他のセッションやライトニングトークもどれも興味深い内容ばっかりやった。とくに個人的に苦手意識の強いテスト関連の内容に関しては、学んだ事をこれから個人的に実践していきたいし、便利なソフトウェアもガンガン導入していきたいと思った。がんばる。Pylonsももっと触ってみよう。

そんなこんなで今年も合宿は終了。皆様お疲れ様でした。当日録画した動画はDVから吸い出してwmvにエンコードしてblip.tvにアップしたのでご覧あれ。今回は中継も取り込みもエンコードもアップロードもすべてWindows上で作業した。楽チン。実はLinuxでいけるんじゃね?って思って合宿前に色々実験してたんやけど、結局無理やったので諦めてWindowsで作業した。その事については後日またエントリに書く事にする。

Python Developers Camp 2008 Winter に参加中。その2

posted by jun-g at Sat, 08 Mar 2008 23:49 JST

2日目のセッション終了。ただいま録画したビデオを取り込み中。取り込みが終わったら高画質版としてどこかにアップする予定。低画質で良い人はustreamに録画したものをどうぞ。

さて、まだPylonsのチュートリアルが終わってない…。急がねば。

関西のTV番組の放送開始を通知するTwitterBot書いた

posted by jun-g at Mon, 14 Jan 2008 02:12 JST

最近Yahoo!TVの番組表ページからiEPGファイルをごっそりダウンロードしてきてお気に入りの番組をiCalendarファイルに書き出す、っていうスクリプトを書いたりしてて、「これってTwitterBotにして全番組を通知するようにしてみようかなぁ」とか思ったので作ってみた。→ TV番組[関西版]。もちろんPythonで書いたよ。

番組放送開始時間にTwitterに投稿したいからcronは使えないよな~、って事でdaemonとして実行するようにしてみた。でもって同じ時間に始まる番組がいくつもあったりするので、マルチスレッドで並列に処理するようにしてみた。マルチスレッドのプログラム書いたの初めてだったので楽しかった。

肝心のソースは後日晒すつもり。

FreeBSD portsのwww/py-django-develのバージョンが上がった

posted by jun-g at Thu, 01 Nov 2007 01:01 JST

FreeBSD portsのDjango開発版のバージョンが、20070525から20071029のスナップショットに上がった。これの対応版みたい。i18n関連の機能はまったく使っていないけど、とりあえず他のアプリもろともportupgradeしておいた。

今回のバージョンアップでSecurityFix以外の変更点ってあるんかな…?とりあえず手元のDjango上で動作している自作のツール類は問題なく動いてるのでホッとした。

Djangoの新規作成の汎用ビューでフォームのデフォルト値を設定したい

posted by jun-g at Sun, 07 Oct 2007 20:32 JST

汎用ビューの勉強がてら、views.pyを一切書かずにツールを作ってみるか、と思って試してみてるんやけど、いきなり躓いた。

作っているツールはちょっとしたメモ用のツールで、画面上、内容と日時を入力するテキストフィールドが表示される。この日時のフィールドにデフォルト値として現在日時を設定しておきたいんやけど、やり方がわからなかった。一応調べたとこまでメモ。

とりあえずdjango.views.generic.create_update.create_objectのソースを読んでみたところ、マニピュレータを自作して、flatten_data()メソッドを実装すれば良さそうな感じがしたので、さらにdjango.db.models.manipulatorsを読んで、モデルクラス内に以下のクラスを追加してみた。

class AddManipulator(models.manipulators.AutomaticAddManipulator):
    def flatten_data(self):
        now = datetime.now()
        return dict(
            rec_time_date = now.strftime('%Y-%m-%d'),
            rec_time_time = now.strftime('%H:%M:%S'))

しかし、ここで定義したクラスはまったく使われていない様子。python manage.py shellを起動して確認してみたところ、モデルのAddManipulatorは<class 'django.db.models.manipulators.AddManipulator'>を参照していたので、自分で定義したAddManipulatorクラスは自動マニピュレータで上書きされているっぽい。

ドキュメント見ても「このビューは、 Django モデルに付属の自動マニピュレータを使います。」って書いてあるしなー…。やっぱり汎用ビューを止めてviews.pyを書いたほうがいいのか…?

Djangoのテンプレートでsettings.pyのMEDIA_URLを参照

posted by jun-g at Tue, 25 Sep 2007 01:36 JST

そういえば静的なコンテンツを一切扱ってなかったなと思い、まず、ドキュメントのmod_python で Django を動かす - メディアファイルの提供を参考にしてApacheの設定を変更。元々/django/以下をdjangoで動くように設定していたので、

<Location "/django/media/">
    SetHandler None
</Location>

とした。後はdjango/media/以下にアプリケーション毎にディレクトリを掘って、その中にメディアファイルを入れればOK。

しかし、テンプレート内の画像タグなんかでURLを全部絶対パスで書いちゃうと可搬性が下がるという問題に気付いた。で、settings.pyにMEDIA_URLっていう設定があった事を思い出したので、それをテンプレートから参照する方法を調べてみたところ、やっぱり同じ事考えている人はいた。

テンプレート上でのMEDIA_URL呼び出しについて その2 | pythonでつくるskyfish開発ブログ

上記ページのeveresさんのコメントを参考にsettings.pyに、

from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = \
    global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    'myproject.context_processors.media',
    )

を追加。で、Djangoプロジェクト直下にcontext_processors.pyを作成し、その中に、

from django.conf import settings
def media(request):
    return {'MEDIA_URL': settings.MEDIA_URL}

と書いた。generic viewsを使っているので、以上でテンプレート内で{{ MEDIA_URL }}と書けるようになった。自前のviewsを使用している場合はcontextにRequestContextを指定しないといけないようなので、忘れないようにしよう。

そういえばドキュメントのコンテキストのサブクラス: RequestContextで、TEMPLATE_CONTEXT_PROCESSORSの値のデフォルトは

("django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media")

になっている、と書かれているけど、自分の環境ではdjango.core.context_processors.mediaという値は含まれていなかったし、実際django/core/context_processors.pyの中にはmediaという関数は存在しなかった。バージョンが違うからかな…?

Djangoを使ってみてる その2

posted by jun-g at Sun, 23 Sep 2007 20:54 JST

チュートリアル通り進めた場合、チュートリアルその3のURLconf の脱カップリングで行った内容だけだとDjangoアプリケーションの切り離しは出来ない。何故ならviews.pyに

from mysite.polls.models import Poll

と書いてしまっているから。これだとmysite以外のプロジェクト内に移動した場合にコードの修正が発生してしまう。完全に切り離すには、

from polls.models import Poll

と書かなければならないと思う。チュートリアルその4まで見たけどこの事についてはどこにも触れられていないっぽい。誰でもすぐ気付くからかな?

ちなみに、Django付属の開発用サーバではimport文を上記のように書き換えてもそのまま動くけど、Apache+mod_python上ではPythonPath上にpolls.modelsが見つからない、というエラーになった。ドキュメントのmod_python で Django を動かすには、DjangoプロジェクトおよびDjangoアプリケーションそれぞれの親ディレクトリをPythonPathに含める必要がある、と書いてあった。なので例えば/home/jun-g以下にチュートリアル通りの以下のようなディレクトリ構成で配置した場合、

mysite
  |
  +-- polls

PythonPathには以下のように書く必要がある。

PythonPath "['/home/jun-g', '/home/jun-g/mysite'] + sys.path"

っていうポイントにちょっとだけ引っかかった。

後、作成した自分用のアプリの入力フォーム生成とデータのバリデーションをnewformsを使うように修正した。泥臭いコードがかなり減ったけど、もうちょっと適切なWidgetを適用すればまだまだ整理できそうな感じ。そういえば、ドキュメントにoldformsの事は知らなくて良い、と書かれていたので、oldformsには一切触れず。

あ、generic viewsもmiddlewaresもまだ全然触っていない。これは次のアプリで使ってみることにしよう。後、動作環境をApache+mod_wsgi上に移す、とかもやりたい。

Djangoを使ってみてる

posted by jun-g at Fri, 21 Sep 2007 13:07 JST

個人的なメモツールをいくつか作る必要があったので、勉強がてらDjangoでひとつ作ってみた。DjangoはFreeBSD portsのwww/py-django-develからインストールした。バージョンは2007/05/25あたりのスナップショットみたい。

とりあえず最初はチュートリアルを見ながら始めた。で、だらだらやってた割にすぐできた。やっぱり和訳ドキュメントが揃ってると便利やなぁ。でも、すぐ出来ただけあってとりあえず動きました的な実装になってしまったので、まだまだ改善の余地有り。formsとかgeneric viewsとか全く使ってないし。

そういえばなんか時間が-9時間ずれてしまって、ちょっとだけハマった。原因はsettings.pyのTIME_ZONEに「Asia/Tokyo Japan」と書いてしまっていたから。正しくは「Asia/Tokyo」だけで良いみたい。settings.pyに載っていた参考URLのこのページには「Japan」まで書かれてたから、その通り書いただけなんやけどな…。

Apache+mod_pythonで動かす為の環境構築まで完了したので、コードをちょっとづつ修正していくか。

japanese/py-mecab とか

posted by jun-g at Tue, 28 Aug 2007 00:15 JST

MeCabのPythonバインディングのportを作ってsend-prした。オフィシャルの奴ね。

オフィシャルじゃないけど高速らしいcmecabも近日中にportを作ってsend-prするつもり。

さて、職場ではどっちを使おうかな。

PyBlosxom 1.4.1 にバージョンアップした

posted by jun-g at Sun, 12 Aug 2007 17:12 JST

1.4が出たしバージョンアップしよう、と宣言しつつしばらく放置してたら何時の間にか1.4.1が出てたので、重い腰を上げて作業してみた。

まずはローカルのテスト環境を1.4.1に入れ替えてみて動作確認、と思って動かしてみたら全然動かん…。デバッグした結果、原因はWSGI Applicationなクラス「PyBlosxomWSGIApp」の中でconfigの設定を空辞書(厳密には違うけど)で上書きしてしまい、設定値がすべて参照できなくなってしまっている為、と判明。こんな誰でも引っかかりそうなバグがいつまでも残ってるわけないよね?と思ってsvnリポジトリを見てみたら、案の定rev.1802で修正済みやった。

一応修正パッチを晒しとこう。

--- pyblosxom.py.orig	2007-08-12 13:36:57.000000000 +0900
+++ pyblosxom.py	2007-08-12 13:49:37.000000000 +0900
@@ -468,7 +468,7 @@
         import config
         self.config = dict(config.py)
 
-        self.config = _config
+        self.config.update(_config)
         if "codebase" in _config:
             sys.path.insert(0, _config["codebase"])

ちなみにWSGI環境(っていう表現って妥当…?)で動作させない限りこのバグは発生しない。でもwsgirefがインストールされている場合、CGIで動作させても内部で強制的にwsgirefのCGIHandlerを使ってPyBlosxomWSGIAppクラスを実行する仕組みになっているので、このバグが発生してしまう。wsgirefはPython 2.5から標準ライブラリに含まれるようになったので、Python 2.5の人は特に要注意って事で。

Python Workshop the Edge 2007

posted by jun-g at Sun, 01 Jul 2007 02:08 JST

あーやっぱり行けばよかった…とライブ中継を見ながらかなり後悔した。

distutilsでCコンパイラにMinGWを使うように設定

posted by jun-g at Sun, 17 Jun 2007 19:43 JST

distutils/setuptoolsを利用してライブラリをインストールする際、ライブラリによってはCコンパイラを要求してくる場合がある。Windowsの場合標準ではCコンパイラがインストールされていない上、distutilsのデフォルトの設定だとCコンパイラにVCを要求してくるので、MinGWを使用するように設定してみた。

まずはMinGWのインストール。MinGWについては全然詳しくないので、C-Compiler Wiki - MinGW/インストールのページを参考にインストール、および設定を行った。

MinGWのインストールが完了したら、次にdistutilsの設定。distutilsのディレクトリ(Python2.5のデフォルトインストールパスだと、C:\Python25\Lib\distutils)の中に「distutils.cfg」というファイルを作成し、そのファイルに下記を記述して保存した。

[build]
compiler=mingw32

以上の設定でコンパイラにMinGWが使用されるようになった。これでeasy_install使ってガンガンライブラリをインストールできるようになったぜ!という事で一件落着。

Mod_pythonアプリケーションをpdbでデバッグ

posted by jun-g at Mon, 28 May 2007 17:47 JST

今年の2月にリリースされたMod_python-3.3.1から、ディレクティブで設定できる項目が沢山増えてる事にこないだ気づいた。その中にPythonEnablePdbっていう設定を発見。え?mod_pythonでpdb使えるの?って事で試してみた。

test.pyとして以下のコードをpublic_html直下に置いた。

# coding: utf-8

from mod_python import apache

def handler(req):
    req.content_type = "text/plain"
    req.write("Hello, Mod_python!\n")
    return apache.OK

でもって.htaccessに以下を設定を書いた。

AddHandler python-program .py
PythonHandler test
PythonEnablePdb On

ブラウザからリクエストを投げてみると、何事もなくブラウザ上に「Hello, Mod_python!」と表示された。ドキュメントには「httpdを-DONE_PROCESSオプションを付けて起動せよ」と書いてあるので、その通りapacheを再起動してみる。

# apachectl -k stop
# apachectl -DONE_PROCESS

すると、コマンドライン上はプロンプトが返ってこず、応答待ちの状態となった。psコマンドで見てみると、httpdプロセスはひとつだけ動いてる状態になっている。

# ps ax | grep http
78398  p4  S+     0:01.73 /usr/local/sbin/httpd -DONE_PROCESS

この状態でブラウザからリクエストを投げてみると、応答待ちだったコマンドライン上でおもむろにpdbが起動し、コマンド入力待ちになった。適当にpdbのコマンドを実行してみる。

> /home/jun-g/public_html/test.py(6)handler()
-> req.content_type = "text/plain"
(Pdb) l
  1     # coding: utf-8
  2  
  3     from mod_python import apache
  4  
  5     def handler(req):
  6  ->     req.content_type = "text/plain"
  7         req.write("Hello, Mod_python!\n")
  8         return apache.OK
  9  
[EOF]
(Pdb) p req.uri
'/~jun-g/test.py'
(Pdb) r
--Return--
> /home/jun-g/public_html/test.py(8)handler()->0
-> return apache.OK
(Pdb) s

最後まで実行すると普通にブラウザに応答が返ってきた。なるほど。本当にpdbでデバッグできるようになってるみたい。

しかし…これは…便利なのか…?普段ほとんどpdbを使っていないからかもしれないけど、便利かどうか判断がつかない。個人的には今までどおりprintデバッグで十分かな。あと-DONE_PROCESSで起動した場合のhttpdの止め方がわからん。apachectl -k stopでは止まらなかったので、結局kill -9で殺した。

他に以前のバージョンとの違いで気付いた点は

  • PythonDebugを有効にした場合のトレースバックに色々情報が出るようになった。
  • PythonPathに仮想ディレクトリを指定するとエラーになるようになった。

ぐらいかな。あと、mod_pyhton.util.Fieldもちょっと変わってて、以前書いたコードがそのままじゃ動かなかった。けどそれは以前のコードの書き方がまずかっただけかもしんないので、詳細はふせとこう。

ところでDjangoとかTrac経由じゃなくて、直接Mod_python触ってる人っているんかな…。

東海 Python Workshop 01 に参加してきた

posted by jun-g at Sun, 27 May 2007 18:45 JST

予定どおり、東海PythonWorkshop01に参加してきた。ので大雑把に内容と感想など。

どこでもPython

aodag隊長によるPythonの紹介。Pythonを使っている企業や団体、Pythonで出来る事や特徴、基本的な書き方などを高橋メソッドでザーっと紹介。GUIツールキットの紹介に、py-gtkが含まれていなかったのは何故なんだぜ?

Ploneで快適CMS 導入から使いこなし

nyusukeさんによる、Ploneの紹介。PloneというかZopeはどうも「高機能すぎて難しい」という先入観から来る苦手意識があって、職場に導入こそしているものの、ほとんど使いこなせていない。nyusukeさんの説明はすごく丁寧で、「あ、そんな事も簡単にできちゃうなら、もうちょっとちゃんと勉強して使ってみようかな」という気になった。プロダクトを活用すれば、社内向けにバラバラに動いているサービスも、Ploneに集約できちゃいそうな感じやし。

Djangoで始めるデザイナー的フレームワーク入門

pateoさんによる、デザイナー視点から見たDjangoの紹介。今回の発表用にTwitter風なmonologistaというサイトを作ったとのこと。しかもほとんどGenericViewsだけで出来た、との事。ほとんどコードを書かなくて済むDjangoはデザイナーにおすすめ、という事らしい。なるほど。

Djangoの話で良く出てくるGenericViews、いまだに何の事なのかさっぱりわからない。そろそろ一度Djangoを触ってみた方が良いのかも。

WSGIの日々 名もなきフレームワーク

再度aodag隊長の発表。WSGIの概要紹介と、aodag隊長が制作中のオレオレWEBアプリケーションフレームワークの構成と設計の紹介。知らない名前が大量に出てきたのでメモメモ。

lightyってlighttpdの事だったのか。知らんかった。

ここからはライトニングトーク。

CASによるDjango,Plone間でのシングルサインオン

佐古田さんによるライトニングトーク。CASってのはCentral Authendication Serviceという、Servletで動作する認証サーバの事。クライアントの実装も色々あるみたいなので、便利そうでいいなーと思った。でもこういう認証サーバって、ユーザー毎アプリ毎のロールの設定とかも出来るんかな…?

それってPythonプログラミングなの?

ymasudaさんによる、PythonからCのライブラリなんかを操作する方法についての話。紹介された方法は、

の4つ。PyInstantはPythonコード中にCのコードを埋め込み、実行するとおもむろにコンパイルが始まるらしい。ワラタ。

やってみよう視覚化

jbkingさんによる、Graphvizを使って、コードからドキュメントだけじゃなく、グラフをも自動生成してしまえ、という「書かない技術」ならぬ「描かない技術」の話。すげーっす。あと、VPythonを使って、3Dで視覚化するというネタもあるそうな。おもろい。

Webテストツール pamie

Hanaokaさんによる、IE自動操作ツールpamieの紹介。自動操作なのでテスト以外にも色々使えるよね、というお話し。面白そうなので休み明けに職場のPCに早速インストールしてみよう!

Pythonコミュニティとの付き合い方

kfuruhataさんによる、勉強会や合宿の紹介。Pythonistaはみんなまじめで合宿大好き。勉強会は男だらけ。そして合宿で皆でギューギューになりながら露天風呂につかって親密になりすぎる、と。ちょ、それって…w

以上でWorkshop終了。でもって場所を居酒屋に移して懇親会。全員の方とお話できなかったのが残念やったけど、楽しかった。相手してくれた皆様、ありがとうございました。ちなみに、メガネ+モヒカンの人が僕です。名古屋は大阪からだと新幹線で一時間程度で行けるので、今後も東海イベントには気軽に遊びに行きたいな~と思った。

皆様お疲れさまでした。

py-hyperestraier-python

posted by jun-g at Thu, 05 Apr 2007 23:55 JST

SWIG版のPython用HyperEstraierライブラリはノードAPIを含まないので、lirisさん作のPurePythonHyperEstraierライブラリを使(ってもら)うことにした。ソースを見るとSWIG版とインターフェースがそっくりだったので、移行は超簡単やった(らしい)。使っているうちに何箇所かバグを発見した(とのことな)ので、パッチを作ってlirisさんに送って取り込んでもらった

微妙に伝聞調?なのは、実際にライブラリを使ったのとバグを発見したのは僕ではないから。人の手柄を横取り…したわけではないのであしからず…。

それから、FreeBSD用のportsを作ってsend-prしておいた。SWIG版のライブラリとport名がかぶってしまうので、PKGNAMESUFFIXに「-python」って付けてみた。commit待ち。

pythonでimport文で指定したクラスを動的生成したい

posted by jun-g at Tue, 03 Apr 2007 02:16 JST

ここんとこずーっと悩んでて解決方法がわからんのでブログで晒してみる。

pythonでMochiKit.DOMのcreateDOMみたいのがあったら便利かなと思って下記のようなクラスを書いた。

class Tag:
    """A base class of HTML tag."""

    name = None
    inline = True
    container = False

    def __init__(self, *nodes, **attributes):
        self.nodes = nodes
        self.attributes = attributes

    def __str__(self):
        return self.serialize()

    def serialize(self):
        text = ""
        for node in self.nodes:
            if isinstance(node, Tag):
                text += node.serialize()
                if not node.inline:
                    text += "\n"
            else:
                text += node
        tag = "<" + self.name
        attrs = map("=".join, [(x[0], "\"%s\"" % (x[1])) for x in self.attributes.items()])
        if len(attrs) > 0:
            tag += " " + " ".join(attrs)
        if text == "":
            tag += " />"
            if self.container:
                tag += "\n"
        else:
            tag += ">"
            if self.container:
                tag += "\n"
            tag += text + "</" + self.name + ">"
        return tag

サニタイズとか全然してないけど、とりあえずなのであまり気にしない。こいつから各タグのサブクラスを作っておくと、

class DIV(Tag):
    name = "div"
    inline = False
    container = True

class A(Tag):
    name = "a"
    inline = True
    container = False

下記のように使える。

>>> a = A("DaemonFreaks.com", href="http://www.daemonfreaks.com/")
>>> div = DIV("僕のサイト: " , a, style="border: 1px solid #000000;")
>>> print div
<div style="border: 1px solid #000000;">
僕のサイト: <a href="http://www.daemonfreaks.com">DaemonFreaks.com</a>
</div>

でもって、タグを全部クラスとして定義するのもアレなので、クラスを動的に生成する関数を作った。

from new import classobj
def _get_class(name, inline, container):
    name = name.lower()
    cls = classobj(name.upper(),
                   {"name": name,
                    "inline": inline,
                    "container": container})
    return cls

で、各タグの名前、inlineとcontainerの設定を用意しておけば準備完了。

# name: (inline, contaier)
TAGS = {
    "html": (False, True),
    "head": (False, True),
    "body": (False, True),
    (省略)
    "div":  (False, True),
    "span": (True, False)
    }

後は、import文が呼び出された際に、「import *」なら定義内容すべてのクラスを、タグが指定されたなら指定タグのクラスをグローバル空間に展開するようにしたい。つまり、モジュール「html」内にこれらのコードが書かれていたとして、

>>> from html import HEAD, BODY
>>> dir()
['HEAD', 'BODY']
>>> from html import *
>>> dir()
['HTML', 'HEAD', 'BODY', (省略), 'DIV', 'SPAN']

のように動作させたい。

しかし、同一モジュール内で__import__をオーバーロードしたりihookを使用してみたものの、どうも期待どおり動作しない。同一モジュール内にオーバーロードの処理を書くと、そのモジュールがimportされた後に__import__がオーバーロードされてしまう(当たり前か…)。なので、モジュール内で自分自身を再度インポートするように記述するとなんとなく上手く動いてるような感じにはなる。

importされるモジュール側でimportをhookして、指定されているクラス(orモジュール)名を取得する方法は無いものか…。

PyBlosxom on mod_wsgi

posted by jun-g at Thu, 22 Mar 2007 03:36 JST

mod_wsgiのリリース間近でなんとなく盛り上がっているふうなので、僕も試してみた。

やっぱり動かすならPyBlosxomだよねぇ(Wikiにも載ってないし)という事で、Apache2.2 + PyBlosxom(svn trunk版)で動かす事に。

インストールはaodag隊長んとこに書いてあるとおり、

./configure && make && make install

で完了。当然事前にpythonとapacheがインストールされている必要あり。後はディレクトリ作ってPyBloxsomのソース一式を突っ込んでから、Apacheの設定ファイルに以下を追加した。

LoadModule wsgi_module libexec/apache22/mod_wsgi.so
(略)
WSGIScriptAlias /pyblosxom /usr/local/www/apache22/wsgi/wsgi_app.py
<Directory "/usr/local/www/apache22/wsgi">
(略)

で、あっさり動いた。素晴らしい。っていうか元々WSGI対応の作りになっているので当然そのままで動くんやけど。

Pyblosxom on Mod_Wsgi
Pyblosxom on Mod_Wsgi posted by (C)jun-g

mod_wsgiで動かすのは簡単やったけど、trunk版のPyBlosxomに新しい設定項目(locale)が追加になってて、そこに少しハマったという…。

DevCampの写真

posted by jun-g at Sun, 18 Mar 2007 03:30 JST

DevCampの時、携帯電話のカメラで3枚だけ写真を撮った事を思い出した。しかし、Flickrのアカウント情報を壊れたデスクトップPCの中に置き去りにしたままなのでログインできない…という事でPythonista御用達らしいフォト蔵にアカウントを取ってアップしてみた。

posted by (C)jun-g

おっと、合宿らしい写真は3枚のうちの1枚だけやった…。

PyXPCOMを使ってみよう

posted by jun-g at Sun, 18 Mar 2007 03:02 JST

Lingraodag隊長voluntasさんと会話中にPyXPCOMの話題になり、最近のMozillaのソースには普通にPyXPCOMのソースが含まれている事を教えてもらったので早速ビルド/インストールしてみる事にした。…とはいえ自前でソース取ってきて一からビルドできる程の知識は持ってないので、ここを参考にしながらportsを改造する事に。FreeBSD万歳!!

って事で以下はwww/mozilla/Makefile.commonのパッチ。

--- Makefile.common.orig	Sat Mar 17 01:35:11 2007
+++ Makefile.common	Sat Mar 17 03:34:09 2007
@@ -119,7 +119,7 @@
 LDFLAGS+=		-L${X11BASE}/lib -Wl,-rpath,${PREFIX}/lib/${MOZ_RPATH}
 LIBS+=			${PTHREAD_LIBS} -L${LOCALBASE}/lib -liconv
 
-_USE_GECKO_OPTIONS_ALL=	java debug logging optimized_cflags
+_USE_GECKO_OPTIONS_ALL=	java python debug logging optimized_cflags
 
 .if !defined(USE_GECKO_OPTIONS)
 USE_GECKO_OPTIONS=	debug logging optimized_cflags
@@ -127,6 +127,7 @@
 
 debug_OPTION=	"Build a debugging image" off
 java_OPTION=	"Enable JAVA xpcom" off
+python_OPTION=  "Enable PyXPCOM" off
 logging_OPTION=	"Enable additional log messages" off
 optimized_cflags_OPTION=	"Enable some additional optimizations" off
 
@@ -214,6 +215,11 @@
 JAVA_OS+=	native
 CONFIGURE_ENV+=	JAVA_HOME="${JAVA_HOME}"
 MOZ_OPTIONS+=	--enable-javaxpcom
+.endif
+
+.if defined(WITH_PYTHON)
+USE_PYTHON=	yes
+MOZ_EXTENSIONS+=python/xpcom
 .endif
 
 .if defined(WITH_LOGGING)

PyXPCOMを有効にする対象はXULRunnerにしよう、という事で、次はwww/xulrunner/Makefileのパッチ。

--- Makefile.orig	Sat Mar 17 01:38:02 2007
+++ Makefile	Sat Mar 17 03:35:18 2007
@@ -29,7 +29,7 @@
 		--enable-system-cairo
 MOZ_EXTENSIONS=	default,cookie,permissions
 OPTIONS=	# Empty, used for generic gecko OPTIONS
-USE_GECKO_OPTIONS=	java debug logging optimized_cflags
+USE_GECKO_OPTIONS=	java python debug logging optimized_cflags
 
 .include 
 .include "${PORTSDIR}/www/mozilla/Makefile.common"

この2つのパッチを適用したら、www/xulrunnerのオプションに「Python」ってのが出るようになる。

でもって早速make installして試してみた。

/home/jun-g% python
Python 2.4.4 (#2, Feb 24 2007, 05:43:34) 
[GCC 3.4.6 [FreeBSD] 20060305] on freebsd6
Type "help", "copyright", "credits" or "license" for more information.
>>> import xpcom
>>>

出来た!!という訳で今回はここまで。次はここ見ながらもうちょっと試してみよう。

関西 Python Workshop 01 に行ってきたよ

posted by jun-g at Sun, 18 Mar 2007 02:32 JST

関西初のPythonWorkshopようやく開催!というわけで行ってきたよ。増田さんによるDjangoの解説も、濃い〜話満載のライトニングトークも、どれも面白かった。

その中でも、aodag隊長のWSGIの解説が実に分かり易くてよかった。興味のある内容だったし。WSGIの事もっと勉強しないと。

その後懇親会に参加。増田さんの向かいの席で超緊張したw

Python Developers Camp 2007 Winter に行ってきたよ

posted by jun-g at Thu, 15 Mar 2007 03:22 JST

既に帰ってきてから一週間以上過ぎちゃったし、そろそろ感想とか書かないと。とはいえ、しばらくの間blogの更新してなくてすっかり文章が書けない体になってしまったので、覚えてる事だけ箇条書きにしようそうしよう。

  • 出発日、朝起きたら新幹線の出発時間だった。
  • 行きの特急電車の中でdWの記事を読んでTurboGearsの勉強をしていたら気分が悪くなってきて、1時間程デッキでうずくまって過ごした。
  • 雪を久しぶりに見た。
  • 持込荷物が多くて重かった。
  • nyusukeさんのプレゼンにおおっと思う内容が多かった。「YUIのreset.css」、「nukamiso.css」など。あと「HTML/CSS/JavaScriptはクライアント側のMVC」という表現に感動。
  • The 20 Minute Wikiは、和訳されてないので読み飛ばし率80%、かかる時間は5時間ぐらい(集中してないから?)、Typoで動かず延々ハマる。
  • VPythonすげー。そしてLingr盛り上がり杉。
  • 温泉最高!
  • TurboGearsチームは、寝るのは夜遅く、起きるのは朝早かった。
  • skyfishって何なんだ!?
  • 睡眠時間短いとやっぱり眠い。
  • カレーが辛い。
  • TurboGearsめちゃ面白い。
  • 成果発表、皆レベル高いなぁ。
  • 動画配信用にDVカメラを持ち込んでおいて、撮影は全てまかせっぱなしという無責任さ。(清水川さん、中島さん、お疲れさまでした!)

ってな感じか。もうあんまり覚えてない…。でも、すんげー楽しい3日間やった。運営の皆様、動画配信チームの皆様、そして参加された皆様、お疲れさまでした!

Python Developers Camp 2007 Winter

posted by jun-g at Fri, 02 Mar 2007 01:24 JST

明日(いや、もう今日か…)から開催されるdevCampに現地参加してきます。わくわく。

PyJUG同時多発忘年会 関西編

posted by jun-g at Fri, 08 Dec 2006 00:23 JST

昨日はPyJUG同時多発忘年会に参加してきました。会場は梅田風月。参加者4名でまったり飲み喰いしました。ごちそうさまでした。楽しかったです。

PyJUG同時多発忘年会 大阪

emma on FreeBSD

posted by jun-g at Sun, 03 Dec 2006 04:25 JST

何気なくMOONGIFTを見ていたら、emmaというPythonで書かれたMySQLのGUIツールを発見した。(MOONGIFTのemma紹介ページ)

ムラムラと使ってみたくなったのでports treeの中を探してみたけど見付からず、仕方なくソースからインストールした。

が、よくよくソースを見てみるとPythonのファイルとアイコン画像ぐらいしか存在しなかったので、これなら簡単と思い、portsを作ってsend-prしといた

肝心のemmaの使い勝手などは、まだほとんど試せていない。とりあえず、MySQL-4.0.xでサーバ/クライアントともにcharset=SJISの環境では、テーブルに格納された日本語データが全部文字化けしてしまう事だけは確認できた。ってそれじゃ全然使われへんやん…。

関西オープンソース2006とPythonista懇親会

posted by jun-g at Sun, 19 Nov 2006 10:36 JST

昨日18日は予定どおり関西オープンソース2006に行ってきたよ。

これまた予定どおり寝坊して昼過ぎに起きたので、現地に到着したのは15時ぐらい。13時からの「Plagger入門」と「プログラミング言語Haskell」どっち聞こうかなぁ、とか迷ってたけど、そもそもどっちも聞けねーよ、みたいな。

やや迷いながらもなんとか展示ブースのある部屋に到着。今年はメイドさんがいた。「あんまり話かけないでね」オーラをゆんゆん出しつつ、展示ブースを足早に見てまわって適当に資料をもらってから、セミナーをやってる5Fに移動。

ちょうど「オープンソースERP Compiereの技術と日本での事例」というのをやっていたので、潜り込んで聞いてみた。うちの会社の場合、ERPが担うべきシステムもすべてお手製で作っていて、業務側からの要望で入れた痒いところに手が届く機能が大量に実装してあったりするので、SAPだろうがこういったオープンソースERPパッケージだろうが、外部製のシステムに入れ替えるのは大変だろうなぁ、という印象(当り前か…)。ただ、そもそも僕自身が「一般的なERPでは(例えば受注管理、在庫管理などの)業務はこういうフローで処理する設計になっている」みたいなセオリー的な事を知らないので、そういった事の参考にはできるかなぁ、と思った。セオリーがあるのかどうかは知らないけど。

次はお目当ての「Pythonのオブジェクト指向入門」を聞いた。立見出まくりで大盛況。Python人気あるなぁ。セミナーの内容は、リストなんかの組込み型を使って、Pythonではクラスはこうなってますよー的な内容を検証かつ説明。「クラスは型」というのは確かに目からウロコやったかも。セミナー終了後、PyJUG Workshop運営部会の活動報告。いよいよ関西でも勉強会開催か?的な流れになっているので楽しみ。

次は「Webアプリケーションのアクセシビリティ入門」を聞いた。職場で「アクセシビリティ!ユーザビリティ!」と声高に叫んでるのに、自分で作ったページがアンチ読み上げブラウザな作りになっている事が発覚してしまった。不勉強を反省。職場のWEBデザインチームにアクセシビリティの勉強をさせる事にしようっと。

で、本日の真の目的である「Pythonista懇親会」に参加。対人恐怖症なので、酒の力を借りつつも楽しく過ごさせて頂きました。話相手になってくれた皆様、ありがとうございました。SH1.2 PYBLOSXOMのshunuhsさんにお会い出来た事と、柴田さんに「みんPy」にサインを頂けた事が最大の収穫、というかこれが闇の目的だったので、目的達成っと。セミナー講師の森さんと幹事(かつ同僚)の古畑さんは超GJという事で、皆様お疲れさまでした。

みんPyサイン

関西オープンソース2006

posted by jun-g at Thu, 16 Nov 2006 23:58 JST

明日17日と明後日の18日、南港ATCにて関西オープンソース2006が開催される。去年までは開催場所が堺筋本町の大阪産業創造舘だったので、金曜日は昼から(本町の)職場を抜け出して遊びに行ったりできたけど、今年は南港なのでさすがに抜け出して遊びにいくわけにもいかず、金曜は諦めて土曜日だけ遊びに行くことにした。

Python関連は「Pythonのオブジェクト指向入門」というプレゼンと、PyJUGのブース出展がある。夜はPythonistaの懇親会があるとのことなので、こちらも事前に申し込んでおいた。楽しみ〜。

あ、そういえば明日(17日)の夜はHOSPITAL NIGHTがあるんやった。土曜は寝坊しないように気をつけないと。

Pythonでミクシィ日記に投稿

posted by jun-g at Sun, 12 Nov 2006 18:19 JST

ミクシィ日記はチラシの裏扱いしているので「友人まで公開」にしている。でもそうしてると数少ないマイミク達はどうしようもないチラ裏日記ばかり読んでしまってこのブログを全然読んでくれない為、僕について「このゲス野郎め!」みたいな印象しか受けなくなってしまうという問題が考えられる。これは大問題!!

という事で、前の「vimでpyblosxomのエントリを書いてアップロードするvimスクリプトをpythonで書いた」を拡張して、「uploadEntry()」を実行したらエントリをアップロードしつつミクシィ日記にもタイトルとURLを投稿するようにしてみる事にした。

まずは同じような事考えてる人いないかな〜という事でググってみると、そのものズバリ「mizzy.org - ブログを書いたら mixi 日記に自動投稿」というエントリを発見。しかしPerlだった。うーん。ということで検索キーワードに「python」を加えて探してみたら、lirisさん作の「MIXI Pythonライブラリ」と、それをsetomitsさんがメンテナンスした「mixi python ライブラリ」を発見。素晴らしいっす。しかし、ライブラリには日記投稿系のメソッドが実装されていなかった…。めげずにもうちょっと調べてみると、Perlの「WWW::Mixi」には投稿系のメソッドも実装されているということで、これを参考にしながら、日記投稿メソッドを自分で実装することにした。

まずは「mixi python ライブラリ」からpymixiをダウンロードして展開。BeautiluSoupUniversal Encoding Detectorも必要、との事なのでインストール。僕はFreeBSDを使っているので、ports treeから、

# cd /usr/ports/www/py-beautifulsoup/
# make install clean
# cd /usr/ports/textproc/py-chardet/
# make install clean

でインストール完了。とりあえず動くか試してみる。

$ python mixidiary2txt.py -u MAILADDRESS -p PASSWORD

まったく問題なく動いた。という事で、元となっているクラスモジュール「mixi.py」に日記投稿用メソッドを追加する作業に。とりあえずWWW:Mixiのリファレンスを読むと、最低限必要なパラメータは

idミクシィID。
diary_titleタイトル。
diary_body本文。
submit画面遷移用パラメータ。
編集画面->確認画面遷移時の値は「main」。
確認画面->投稿時の値は「confirm」。

という事がわかった。後、クロスサイトリクエストフォージェリ対策(と思われる)ランダムトークン「post_key」が確認画面で発行されるので、確認画面から「post_key」を取得する必要がある事もわかった。

つー事で、「mixi.py」のクラス「MIXI」に以下を追加。

    def _post_diary(self, mixiid, title, body, submit="main", postkey=""):
        params = urllib.urlencode({"id": mixiid,
                                   "diary_title": title,
                                   "diary_body": body,
                                   "submit": submit,
                                   "post_key": postkey})
        try:
            f = self.opener.open("%s/add_diary.pl" % MIXI_BASE_URL, params)
            data = f.read()
            f.close()
            return BeautifulSoup.BeautifulSoup(data)
        except:
            return None

    def post_diary(self, title, body):
        soup = self._post_diary(self.mixiid, title, body)
        if soup == None:
            return False
        postkey = soup.find("input", {"name": "post_key"})["value"]
        soup = self._post_diary(self.mixiid, title, body, "confirm", postkey)
        if soup == None:
            return False
        return True

Pythonから使うには、

from mixi import MIXI
m = MIXI()
m.login(MAILADDRESS, PASSWORD)
m.post_diary("日記タイトル", "日記本文")

でOK。

これにて問題解決!!

python2.5 on FreeBSD その3

posted by jun-g at Sat, 14 Oct 2006 07:04 JST

ports treeのPythonのデフォルトバージョンが2.4に戻ったみたい。デフォルトバージョンが2.5になるのは6.2R向けのports freeze期間が終了してから、という事らしい。

python2.5 on FreeBSD その2

posted by jun-g at Thu, 12 Oct 2006 01:24 JST

前回書いたコマンドをそのまま実行しても、途中で色々問題が出て全然アップグレードは完了していなかった。portsのMakefileを修正したり、リビルドしたりしてようやくアップグレード完了。

python2.5 on FreeBSD

posted by jun-g at Tue, 10 Oct 2006 01:44 JST

FreeBSD portsのpythonがようやく2.5になったみたい。「lang/python25」が新たに追加された模様。詳細はUPDATING参照。

2.4->2.5のアップグレードは、

cd /usr/ports/lang/python
portupgrade -R
pkgdb -uf
make upgrade-site-packages

で完了。

vimでpyblosxomのエントリを書いてアップロードするvimスクリプトをpythonで書いた

posted by jun-g at Mon, 09 Oct 2006 22:53 JST

pyblosxomは、テキストファイルにエントリを書いてFTPでサーバにアップロードする、という仕組みになっている。プラグインで拡張する事でMetaWeblogAPIを使ったり投稿画面を付けたりする事ができるみたいやけどまだ全然試せていなくて、エディタでエントリを書いてアップする、という作業がかなり面倒に感じていた。

そんな時、「pythonを使ってvimからGoogleカレンダーに予定を投げる (ueBLOG)」というエントリを読んで、ちょうどエディタはvimを使ってるし、「Pyblosxom用エントリファイルのFTP送信」を読んで「Emacs便利でいいなー」とか思ってたので、vimでエントリを書いてそのままアップロードできるスクリプトをpythonで書いてみた。

python << EOF

FTP_SERV = "your.ftp.server"
FTP_USER = "ftpuser"
FTP_PASS = "ftppasswd"
LOCAL_DIR = "/path/to/localdir"
REMOTE_DIR = "/path/to/remotedir"

import vim
import datetime
from os import path
from ftplib  import FTP

def createEntry():
    fileName = path.join(LOCAL_DIR, _createFileName())
    vim.command("new %s" % fileName)
    vim.command("set fileencoding=utf-8")
    cb = vim.current.buffer
    cb[0] = "title"
    cb.append("#tags hoge,fuga")
    cb.append("body")
    vim.command("w")

def uploadEntry():
    cb = vim.current.buffer
    if cb.name == None:
        fileName = _createFileName()
        fullName = path.join(LOCAL_DIR, fileName)
        vim.command("saveas %s" % fullName)
    else:
        fileName = path.basename(cb.name)
        fullName = cb.name
        vim.command("w")
    f = open("%s" % fullName, "r")
    ftp = FTP(FTP_SERV, FTP_USER, FTP_PASS)
    ftp.cwd(REMOTE_DIR)
    ftp.storlines("STOR %s" % fileName, f)
    ftp.close()
    f.close()

def _createFileName():
    return "%s.txt" % datetime.datetime.now().strftime("%Y%m%d%H%M")

EOF

これを.vimrcに書いといて、vim上で

:py createEntry()

とすると

title
#tags hoge,futa
body

という空のエントリを新規バッファを開きつつ「LOCAL_DIR」で指定したディレクトリ内に保存する。ファイル名は現在日時を「YYYYMMDDHHMI.txt」として自動生成。二行目の「#tags〜」はtagsプラグインを使っているので。

でもってエントリをつらつら書いたら、

:py uploadEntry()

でアップロード。僕はエントリのカテゴリ分けをしていないので、カテゴリ指定は無し。

vimは全然使いこなせてないので、おかしな事してるところがあるかもしれないけど、これだけでかなり便利になった。vimももっと勉強しないとな。