Python
Feb 26, 2010
lxmlテスト
Pythonのscrapingライブラリのlxmlをちょっとテスト。
#!/usr/bin/python
from lxml.html import fromstring
lh = fromstring(file('2007.shtml').read())
for i in lh.xpath('//a[img[@src="foo.jpg"]]'):
print i.values()
Feb 11, 2010
ttyをPythonで扱う
ダウンロードの進行表示ってどうやってんのかねと思った次第。
例えばダウンロードの表示をコンソールでやるとして流れていかないで同じ行で表示させているのはどうなってるいのかというのをしらべる。ttyをいじるんだなってのはわかってpythonのttyモジュールを調べたがあんまり解説がないねと。詳解UNIXプログラミングなんぞを久しぶりにひっぱりだしてごにょごにょやってみた。
import tty
import sys
import time
import signal
from pprint import pprint
from termios import *
mode = tcgetattr(sys.stdout)
def handler(signum, frame):
print "signal\n"
tcsetattr(sys.stdout, TCSAFLUSH, mode)
sys.exit(0)
signal.signal(signal.SIGINT, handler)
tty.setcbreak(sys.stdout)
for i in range(20):
if i % 3 == 0 and i > 0:
sys.stdout.write("\n" )
sys.stdout.write("%d\r" % i )
sys.stdout.flush()
time.sleep(1)
tcsetattr(sys.stdout, TCSAFLUSH, mode)
こんな感じですかね。Control-Cを処理できないと何かと面倒なのでsignal処理も付け加える。
Jan 29, 2010
SQLAlchemyを少し
単純なひとつのテーブルをDBで管理しようとおもってORMとしてまだ使ったことのないSQLAlchemyをつかってみた。
むかーし、SQLAlchemyをちらっと見たときには宣言的な書き方ができなかった気がするが…。だからelixirが出てきたと思ったのだが…。いつのまにかできるようになったようだ。特に難しいことはないな。ORMの書き方もqueryの書き方もdjangoとちょっと違うが、慣れの問題。ちょいちょいとやってOK。なるほど。
Dec 03, 2009
OAuthのプロトコルを自分で実装
Google App EngineでTwitterにOAuthで認証するまで自分でがんばる。
サンプルをわけわからないで動かしていたのをpython-oauthを使ってプロトコルの流れを自分で実装。本来はredirectで自動でやる部分をリンクで手動でやるようにしたのでどういうURLのアクセスしようとしているのか理解できた。なんでRequestTokenのシリアライズをやっているのかが実装してみたら理解できた。もうちょっとあとでデータの流れをきちんと説明できるような状態にしておこう。
本当は先週のうちにやっていれたらPython東海でもうちょっとましな説明ができただろうに、反省。
次の目標はOpenIDか。
Nov 29, 2009
第8回 Python東海
いつもの調子で某所を叩いていたら関係者がいた。
今回 OAuth + Twitter + Google App Engine というテーマで話してみた。30分の予定できっちり30分で終わらせたのはきっちりできたと思う。
ただデモプログラムがサンプルそのまま動かしただけというのがつらかった。OAuthに対する理解もまだ甘いのでプロトコルの説明が少し曖昧。いちおうこんなのもやってますという話にはなった。次回まで2ヶ月あるからそれまでには動いているのではないか、と思っておこう。
手書きメモとホワイトボードでの発表とおそろしいことやったので資料はないです。IT系では珍しいことをやっていた。ラップトップの購入予定は全然ないしなあ…。
他メモ。pyjamasはDebianのsidに入っていてためしたかったのだが放置していた。大体わかったので参考になった。そのうちやる。reST。なんでもいいのでプレゼン用PDFが簡単にかけるならうれしい。
懇親会は全品280円の焼き鳥屋。いろいろ大丈夫かねと心配になってきた。しかし、眠い。途中で寝そうになった。あれはいかん。
Oct 05, 2009
mechanizeを使ってバッチでユーザー追加
python mechanizeを使ってPloneのユーザーをバッチで追加
ゴミユーザーの整合性を取るためにやったので深く考えていない。大体次のようなコードとなった。
#!/usr/bin/python
import mechanize
br = mechanize.Browser()
br.open("http://localhost:8080/plone/acl_users/source_users/manage_users?adding=1")
br.select_form(nr=1)
br['__ac_name'] = 'admin'
br['__ac_password']= 'secret'
br.submit()
users = ["testuser", "user2", "user3"]
for u in users:
br.open("http://localhost:8080/plone/acl_users/source_users/manage_users?adding=1")
br.select_form(nr=0)
v = u
br['user_id'] = v
br['login_name'] = v
br['password'] = v
br['confirm'] = v
br.submit()
実用性を考えるなら色々工夫してみること。
第七回 Python東海
新しく(?)なってから初めての参加のような気がする。
なんかネタがあったら次は発表してみたいものである。ラップトップないけどどうやって発表しような…。
懇親会であまり酒を飲めなかった。前日がひどかったせいだ。そのあともひどかったが。
May 31, 2009
python-mechanizeでcheckbox
python-mechanizeを使ってcheckboxを操作する方法がわからない
br['checkboxname'] に何を代入すればいいんだろう?
unittestのコードを読んだらわかった。valueを渡せばよいということだ <input type="checkbox" name="hoge" value="fuga" />なら ['fuga']を代入すればいい。
Jan 10, 2009
ElementTreeのremove覚書
PythonのElementTreeを使っていてElementを削除するときのメモ
次のようなコードは想像しているようには動かない。
import xml.etree.ElementTree as et
dom = et.parse('sample.xml')
root = dom.getroot()
for e in root: root.remove(e)
別でElementを保持してから実行する必要がある。
for e in [ e for e in root]: root.remove(e)
こういう理解でいいのかな?Pyhon-2.5のreferenceの記述が薄い気がするんだけど…。
Feb 25, 2008
modwsgiとMD5の続き
PythonのMD5がmhash2のMD5とでシンボル名が衝突するのでApacheがまともに扱えなくなる件が解決していた。
440272 でPython2.4のバージョンアップで解決されていた。djangoでログイン処理等ができちんとできることも確認。
Jan 06, 2008
reportlab勉強中
reportlabの勉強を開始する。
- 大きくわけて二つのモードがあると思ってよい。線と文字を配置するモード。文章や表などを適当に流しこむモード。
- Frameを使うと小さな描画領域が作らると思えばよい。
- Templateは使う必要はない。
Jan 03, 2008
python-contract
PEP-0316
python文法チェッカー
pychecker・pyflakes・pylint
-
pychecker 文法チェッカー。できるだけ静的に文法違反を調べる。
-
pylint pycheckerと同じ目的。
-
pyflakes 同じ。module周りが親切。使ってないimportとか警告がでる。
Dec 31, 2007
python-mechanize
stateful programmatic web browsing
ブラウザの挙動をスクリプトでやっちゃうぜ、というモジュール。もともとはPerlがあって、それを参考にPython版が書かれた模様。Ruby版もあります。
Nov 21, 2007
python-dateutil
powerful extensions to the standard datetime module
datetimeを使っていて来月の2日なんてのを求めるのはめんどくさいわけですが、それを簡単にしてくれるモジュール。
Pythonで内包記法を使いまくる
あるPythonスクリプトでforで回していたところを内包記法で書き直す。
一時変数やらappendとかが消えて美しくなった。ちょこっとだけHaskellをやっていたころを思い出す。関数型言語に突入するための準備と思っておこう。3重ネストの内包記法はいいんだろうか?
Oct 31, 2007
modwsgiとMD5
djangoをwsgiで動かそうとすると認証ができない。
なぜかクッキーが有効になってないと表示される。多分セッション回りでおかしいのだという検討がつくが…。djangoのrunserverからは大丈夫でapacheからは駄目という謎挙動。クッキーを見るとsessionidの先頭8文字が0にあるという妙な具合になる。
32bitと64bitとの違いなのかとも悩む。Session.objects.get_new_session_key()を出力させるとやはりおかしい。md5の出力もやはり先頭が0になっている。しかもmd5.new('1')もmd5.new('2')も同じ結果になるがリロードする度に値が変わる。sessionが維持できなかったのはmd5の挙動がおかしいのが原因ということまでは突き止めたが、なぜおかしいのかがわからなかった。
で、探してみると原因が判明。mhash2どシンボル名が衝突していたによるものだった。削除してみたら挙動が正常になった。PHP回りで使用しているんですよねえ。python-2.5からは実装が変更になったから大丈夫らしいが…。
- http://code.google.com/p/modwsgi/wiki/ApplicationIssues (Python MD5 Hash Module Conflict)
Oct 24, 2007
SQLOjbectを使う
データを保存するのに使ってみる。
SQLiteと組み合わせれば非常にお手軽。データの扱いはActiveRecordなのでdjangoの応用が効く。妙な辞書をいじくりまわす必要がなくなるだけでも随分と楽になる。
順序としては…。Webでデータの永続化をするぞ→フレームワークを使う程じゃない→でもCSVとかやだ→DBがいい→でもPostgreSQLとかめんどくさい→SQLiteにしよう→でもSQL書くのめんどくせ→ORM使おう→SQLObjectだ。ということのようだ。
Sep 30, 2007
rml.dtdを探して
RMLのDTDを探す。
前に使っていたのに行方不明になって探すことに。reportlabのパッケージにもないなと思ったが…
http://www.reportlab.com/docs/ にありました。
Sep 16, 2007
trml2pdfで日本語を使う
ReportLabの挙動を学んだところでtrml2pdfで日本語を通るようにする。
UnicodeCIDFontを登録するようにすればいいということがわかった。オリジナルのRMlではdocinit内でregisterCIDFontを使って指定してる。じゃあ、それを解釈するように変更すればいいんだなというのが以下のパッチ。
diff -rN -u old-trml2pdf/trml2pdf/trml2pdf.py new-trml2pdf/trml2pdf/trml2pdf.py
--- old-trml2pdf/trml2pdf/trml2pdf.py 2007-09-16 14:19:49.475214466 +0900
+++ new-trml2pdf/trml2pdf/trml2pdf.py 2007-09-16 14:19:49.975179240 +0900
@@ -35,7 +35,8 @@
#
# Change this to UTF-8 if you plan tu use Reportlab's UTF-8 support
#
-encoding = 'latin1'
+# encoding = 'latin1'
+encoding = 'utf-8'
def _child_get(node, childs):
clds = []
@@ -142,6 +143,7 @@
from reportlab.lib.fonts import addMapping
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
+ from reportlab.pdfbase.cidfonts import UnicodeCIDFont
for node in els:
for font in node.getElementsByTagName('registerFont'):
@@ -152,7 +154,11 @@
addMapping(name, 0, 1, name) #italic
addMapping(name, 1, 0, name) #bold
addMapping(name, 1, 1, name) #italic and bold
+ for font in node.getElementsByTagName('registerCidFont'):
+ name = font.getAttribute('faceName').encode('ascii')
+ pdfmetrics.registerFont(UnicodeCIDFont(name))
+
def render(self, out):
el = self.dom.documentElement.getElementsByTagName('docinit')
if el:
これで日本語が通ることを確認した。なおRMLファイルはutf-8にすること。
<!DOCTYPE document SYSTEM "rml.dtd">
<document filename="example_1.pdf">
<docinit>
<registerCidFont faceName="HeiseiKakuGo-W5"/>
</docinit>
<pageDrawing>
<setFont name="HeiseiKakuGo-W5" size="8"/>
<drawCentredString x="2in" y="10in">
こんにちは世界 ゴシック
</drawCentredString>
</pageDrawing>
</document>
元のコードを見ればわかるがTTFontの登録は実装してある。Tinyだけあって最小の努力なのかね。もうちょっと気を使ってもらえるとありがたい。
これでJasperReportsをPythonから無理矢理使おうなんていう頭の痛いことは頑張らなくてもいいようになったかな。

