web.pyで画像アップローダーを

しゃべるにtwitpicみたいなものが欲しくなったので、昼休みに画像アップローダーを書いてみた。

文字列のランダム化はodz bufferを参考にして、ロゴはtwitlogoを使った。

アーカイブはここ

shovelpic

web.pyはstaticっていうディレクトリのファイルは静的なものとして扱ってくれるのと環境変数はweb.ctxでアクセスできる。

#!/usr/bin/env python
# -*- encoding:utf-8 -*-

# kzfm <kerolinq@gmail.com>
import web
import string
from random import randrange

alphabets = string.digits + string.letters

def randstr(n=4):
    return ''.join(alphabets[randrange(len(alphabets))] for i in xrange(n))

image_dir = "images"

urls = (
    '/', 'Index',
    '/(.*)', 'Show',

        )

html_template = """<html><header><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</header><body>
<img src="/static/shovelpic.png" /><br />
%s
</body></html>"""

class Index:
    def GET(self):
        form = """<form method="POST" enctype="multipart/form-data" action="">
<input type="file" name="myfile" />
<input type="submit" />
</form>"""
        return html_template % form

    def POST(self):
        mol = web.input(myfile={})
        if mol['myfile'].filename == "":
           raise web.seeother('/')
        else:
            h = web.ctx.homedomain
            imgid = randstr()
            imgurl  = "%s/%s.png" % (image_dir,imgid)
            imgfile  = "static/%s/%s.png" % (image_dir,imgid)
            f = open(imgfile,"w")
            f.write(mol['myfile'].value)
            f.close()
            snip = "Your imageurl is <a href=\"%s/%s\">%s/%s</a>" % (h,imgid,h,imgid)
            return html_template % snip

class Show:
    def GET(self,imagename):
        img = "/" + image_dir + "/" + imagename + ".png"
        imgurl = "<img src=\"/static%s\" width=500 />" % img

        return html_template % imgurl

if __name__ == "__main__":
   app = web.application(urls, globals())
   app.run()

web.pyはちょっとしたものを書くときには便利だ。

pasteとwsgirefでhttpserver

参考

paste

def app(environ, start_response):
    start_response('200 OK', [('content-type', 'text/html')])
    return ['Hello world!']

if __name__ == '__main__':
    from paste import httpserver
    httpserver.serve(app, host='127.0.0.1', port='8080')

wsgiref

def app(environ, start_response):
    start_response('200 OK', [('content-type', 'text/html')])
    return ['Hello world!']

if __name__ == '__main__':
    from wsgiref import simple_server
    server = simple_server.make_server('', 8080, app)
    server.serve_forever()

app関数は同じ。

egg entry pointsを使ってプラグインっぽいことをしてみた

Eggがよくわからんと少し調べてたら、Python plugins egg cooking mini-howto ってのがわかりやすかったので、デコレーターっぽいことをしてみた。

まず環境汚すのがいやだったのでvirtualenvでテスト環境をつくる。pylonsだとスクリプトでよろしくやってくれるのだけど、自分で作る場合にはvirtualenvwrapperを使うとよいらしい。

というか使ってみると便利すぎ。これは手放せん。

続いて実際に書いてみる。ディレクトリ構造はこんな感じ

$ ls -R deco
minus/     mydeco.py  plus/

deco/minus:
minus_plugin/ setup.py

deco/minus/minus_plugin:
minus.py

deco/plus:
plus_plugin/ setup.py

deco/plus/plus_plugin:
plus.py

ポイントはsetup.pyのentry_pointsってとこで、呼び出す方は entry_pointsに選んだ名前をpkg_resources.iter_entry_points("xxxx")に指定して呼べばいい。

アーカイブはここに置いといた

mydeco.py

#!/usr/bin/env python
# -*- encoding:utf-8 -*-

import pkg_resources

for entrypoint in pkg_resources.iter_entry_points("my.plugins"):
    plugin_class = entrypoint.load()
    decorater = plugin_class()
    print decorater.display("hello world!")

実行結果

$ python mydeco.py 
++++++++++++++++
+ hello world! +
++++++++++++++++

----------------
| hello world! |
----------------

エキスパートPythonプログラミングの4,6章あたりでも触れられており、これも参考になった。

ProductName エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス / ¥ 3,780 ()
在庫あり。

twitterのつぶやきをイントラtwitterに

あらすじ

2010年春、しゃべるを職場に入れてみたところ、ちょっと後ろ向きな発言をする人たちに人気が出てしまい、ネガな雰囲気のただようブラックマイクロブログになりかけていた。

これじゃいかんということで、ポジな発言を紛れ込ませることにしたのであった。


しゃべるのAPIはtwitter互換なのでpython-twitterのハードコードされているurlをしゃべるのそれに変えてやればpythonモジュールがあっという間に出来上がり。ついでにshovel.pyってすればimport shovelで呼べる。

あとはfeedparserでtwitterのポジティブフィードを解析して、一日一回くらいイントラtwitterに注入すればいいわけだ。

import feedparser
import re,os
shuzo_tweet = re.compile("^(shuzo_matsuoka:\ @[^\ ]+ |shuzo_matsuoka:\ )")
d = feedparser.parse("http://twitter.com/statuses/user_timeline/63097969.rss")
stweet = [shuzo_tweet.sub('',e['title']) for e in d['entries']]

import shovel
api = shovel.Api(username='xxx', password='xxx')
users = api.GetFollowers()
followers = [u.screen_name for u in users]

for u,m in zip(followers,stweet):
    message = "@%s %s" % (u,m)
    api.PostUpdate(message)

これで、とりあえずフォロワーに熱いメッセージが送られるようになったが、そのうちちゃんとしたボットを作りたい。

  • おい、そこのお前!ただ漫然と合成するだけじゃテクニシャンと変わんないぞ!
  • 信頼区間がわからなくて、部下の信頼勝ち取れると思ってんのか!このすっとこどっこい
  • 合成数は残業でカバーするもんじゃないぞ、効率だ!こ う り つ!

とか前向きなreplyするやつ(謎)。

repoze.who

pylonsのMLによると、AuthKitは廃止の方向で進むようで。

作者もphase outするって宣言しているし、ここはひとつrepoze.whoでも覚えておこうかなと週末触ってみた。

Authentication and Authorization with repoze.whoをみながらやってみたんだけど、あちこち端折ってあるので、ちょっと簡単には動かせなかった。

というわけでまたあとで。

The Definitive Guide to Pylonsの著者とAuthKitの作者が一緒なので本はAuthKitの利用を前提で書かれていて内容が古い感があるけど、テストのとことか文書化、デプロイメントのあたりはよく書かれているので、手元にあると重宝する。

ProductName The Definitive Guide to Pylons
James Gardner
Apress / 4049円 ( 2008-12-22 )


「エキスパートPythonプログラミング」を読んだ

8章以降はPythonのプログラミングというよりはPythonでプログラミングみたいなメタな話題が多め。

ProductName エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス / ¥ 3,780 ()
在庫あり。

色々バックグラウンドがあった状態で、この本を読めば

あーーーこういう風にやればいいのか!

と沢山の発見があって楽しい。

この本を読めばPythonのプログラミングがバリバリ書けるようになりますよっていうわけではなくて、パイソニスタとしての心構えとか、より良いコーディング習慣の見につけ方みたいな、中長期的な視点での継続的な成長のための本だと思う。良書。

8,9,10章はかなり駆け足なので以下の書籍も読んでおくと吉

ProductName 入門Mercurial Linux/Windows対応
藤原 克則
秀和システム / ¥ 2,310 ()
在庫あり。

ProductName Trac入門 ――ソフトウェア開発・プロジェクト管理活用ガイド
菅野 裕,今田 忠博,近藤 正裕,杉本 琢磨
技術評論社 / ¥ 3,024 ()
在庫あり。

ProductName アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣
Venkat Subramaniam,Andy Hunt
オーム社 / ¥ 2,520 ()
在庫あり。

エキスパートPythonプログラミング

5章まで読んだ。 これは良書ですな。

ProductName エキスパートPythonプログラミング
Tarek Ziade
アスキー・メディアワークス / ¥ 3,780 ()
在庫あり。

  • 第1章 さあ、はじめよう
  • 第2章 構文ベストプラクティス —— クラス以外
  • 第3章 構文ベストプラクティス —— クラスの世界
  • 第4章 良い名前を選ぶ
  • 第5章 パッケージを作る

特に5章のパッケージに関しての章が勉強になった。setup.pyに関して理解が非常に深まった。site-packagesのディレクトリにeggが展開されてない場合があるのはなんでかとか、developコマンド使ってないのでつかってみようとか。あとpasterで独自のテンプレートを作る方法も載っていた。

Pythonクックブックも必読

ProductName Python クックブック 第2版
Alex Martelli,Anna Martelli Ravenscroft,David Ascher
オライリー・ジャパン / ¥ 4,410 ()
在庫あり。

Pythonでtwitpicに写真を投稿する

python-twitpicというものがあった。twitpicはデイレクトリになってて__init__.pyとかあるけど、直接twitpic.pyをimportする方向で。

#!/Usr/bin/env python
# -*- encoding:utf-8 -*-

import twitpic
twit = twitpic.TwitPicAPI('xxxx', 'xxxx')
twitpic_url = twit.upload('twitter.png', message='test from python', post_to_twitter=True)
print twitpic_url

数行で画像投稿しつつtwitterにもpostできる。

pythonでQRコードの生成

X06HTを使い始めてからQRコードの便利さに気づいた

pythonでQRコードを生成するにはlibqrencodeとそのバインディングを使うのが簡単。

import qrencode
qrencode.encode_scaled("http://blog.kzfmix.com/",100)[2].save("qrdrkcore.png")

こんだけ。

qr

シンプソン積分

Javaの課題丸投げ

をシンプソン積分で解けってのがあった。

def simpson(f,a,b,n=1000):
    h = float(b-a)/n
    return (h/6)*sum([f(a+i*h)+4*f(a+i*h+h/2)+f(a+i*h+h) for i in range(n)])

if __name__ == "__main__":
    print simpson(lambda x: 1.0/(1+x**2),0,1)

これをjythonで実行すればJavaの課題を解いたことになるのではないか?

ProductName Jythonプログラミング
西尾 泰和
毎日コミュニケーションズ / ¥ 3,150 ()
在庫あり。