スキップしてメイン コンテンツに移動

投稿

8月, 2008の投稿を表示しています

Python: はてなブックマークのコメント一覧非表示機能について

はてなブックマークのコメント一覧を非表示にする機能が追加された。しかし、新着ブックマークからはコメントが読めてしまう。

例えば、はてなブックマークのコメント一覧非表示機能テストのページはコメントを非表示に設定しているが、その新着ブックマークのページを開くとコメントが表示されていることが分かる。さらに、下記のPythonスクリプトを

hatena_get_comments.py http://d.hatena.ne.jp/fk_2000/20080829/p1

のように実行させると、すべてのコメントとそのユーザ名を表示することができる。

これをGoogle App EngineでWebサービスとすることは簡単だろう。Webサービスの公開はモラルに欠けるようにも思うのでやめておくが、本当にコメントを読めなくするつもりなら今回の非表示機能は中途半端と云わざるを得ない。

因みに、個人的にはコメントを非表示にすることについては賛成とも反対とも考えておらず、あまり関心がない。しかし、はてなブックマークの存在意義にも関わってくるような機能についてはもう少し議論・熟考したほうが良いようにも思える。

hatena_get_comments.py

#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, os, urllib, urllib2, xmlrpclib from HTMLParser import HTMLParser class HatenaHTMLParser(HTMLParser): is_user = False is_comment = False comments = [] current_user = "" current_comment = [] def handle_starttag(self, tag, attrs): if tag == "dd" and ("class", "bookmarker") in attrs: self.is_user = True elif tag == "span&…

Python: はてなブックマークのAPIを使ってみた

最近、はてなブックマークを使い始めたこともあり、はてなブックマークのAPIについて調べてみた。ざっと確認をした後、Pythonではてなブックマーク件数取得APIはてなブックマークエントリー情報取得APIを使ってみた。

はてなブックマーク件数取得APIはブックマークされた件数とAmazonの商品がコレクションされた件数をXML-RPCで取得することができる。一方、ブックマークエントリー情報取得APIでは、はてなブックマークのエントリーの情報をJSON形式で取得することができる。サンプルコードを以下に示す。

#!/usr/bin/env python # -*- coding: utf-8 -*- import urllib2 import xmlrpclib import simplejson url = "http://www.hatena.ne.jp/" asin = "4774124966" # はてなブックマークエントリー情報取得API. data = urllib2.urlopen("http://b.hatena.ne.jp/entry/json/%s" % url).read() info = simplejson.loads(data.strip("(").rstrip(")")) if info: title = info["title"] cnt = int(info["count"]) bookmarks = info["bookmarks"] cnt_user = len(bookmarks) cnt_comment = 0 for b in bookmarks: if b["comment"]: cnt_comment += 1 print b["comment"].strip() if cnt_comment > 0: print print u"タイトル: %s" % titl…

Google: 333333333333335-333333333333334=0?

巷ではGoogleで399999999999999-399999999999998を計算させると0を返すと話題になっているが、ちょうど333333333333335-333333333333334の計算から0を返すようだ。ちなみにこの倍となる数値で計算させると666666666666669-666666666666667=0のように差が2で0を返すようになる。たぶん近いうちに修正されるんじゃないかな。

Google App Engine: Gearsで位置情報を取得してストリートビューで表示させる

Gearsジオロケーション専用のAPI(Geolocation API)がリリースされたのでGoogle App Engineで実装してみた。まず、Geolocation APIで位置情報を取得し、Google MapsおよびGoogle Street Viewにより表示するWebアプリだ。因みに、アプリを実行させるには予めGearsをインストールしておく必要がある。

Geo View

コードは基本的にはStreet Strollを使っており、初期位置情報をGeolocation APIのgetCurrentPositionメソッドにより取得している。下記に示すコードが主な変更部分になる。

Gearsのコアであるgears_init.jsの読み込み。

<script type="text/javascript" src="http://code.google.com/apis/gears/gears_init.js"></script>

初期化関数initialize()の前にinitialize_geo()を噛ませ、変数lat, lngにそれぞれ緯度・経度が入るようにしている。

function updatePosition(position) { lat = position.latitude; lng = position.longitude; initialize(); } function initialize_geo() { if (window.google && google.gears) { var geo = google.gears.factory.create("beta.geolocation"); geo.getCurrentPosition(updatePosition, function(positionError) { alert(positionError.message); }); } else { if (confirm("位置情報を取得するためにはGearsが必要です。インストールしますか?")) { window.location = &qu…

Google App Engine: mixi OpenIDで認証する

mixiがOpenIDに対応したということで早速Google App Engineで実装してみた。以前のエントリで紹介したがGoogle App Engineのサンプル集OpenID ConsumerというWebアプリがあるので、そのソースコードを利用させてもらった。

しかし、実際に使ってみればわかるのだがこのコードにはいくつかのバグ(とGoogle App Engineの制限)があってちゃんと動かない。下記のリンク先は正常に動くように修正したものだ。

mixi OpenID テスト

以下にバグの箇所とその修正コードを示す。

consumer.py

344-345行目の以下のコードを

self.response.set_status(302) self.response.headers['Location'] = redirect_url

以下のように修正する。

self.response.out.write("<html><head><meta http-equiv=\"refresh\" content=\"0;url=%s\"></head><body></body></html>" % (redirect_url,))

これはGoogle App Engineの制限を回避するためで、一度HTMLを表示し同時にリダイレクトを行っている。

fetcher.py

以下の57行目からのコードで、青で示したコードの後ろにある赤で示したコードを青のコードの前に移動させる。

if body: method = urlfetch.POST if 'Content-Type' not in headers: headers['Content-Type'] = 'application/x-www-form-urlencoded' else: method = urlfetch.GET if not headers: headers = {}

また、外部モジュールのPython …

Googleの暗号化ツールKeyczarをPythonで使う

Keyczarから持ってきたKeyczar Python (0.5b)を適当なディレクトリに展開し、srcファイル内のkeyczarをPythonディレクトリのsite-packatesにコピーする。次に、PyCryptosimplejsonASN.1 tools for Python から必要なモジュールをダウンロードしインストールする。

KeyczarToolのPythonの実装として、keyczart.pyが提供されているのでこれを利用する。ただし、これにはバグがあり、そのままだとAddKeyを実行できない。詳細は以下に報告されている。

Issue 21: Incorrect AddKey() Call from keyczart.py main()

対処方法としては、svnで最新版を持ってくるか、以下のようにソースを修正する。

keyczart.pyの113行目の

def AddKey(loc, status, crypter=None, size=None):



def AddKey(loc, status, size=None, crypter=None):

に変更する。

実際に平文を暗号文にし、さらにそれを平文に戻してみる。その前に鍵を作る必要があるので、keyczart.pyで作成する。--locationには鍵を作成したいディレクトリを指定すること。

keyczart.py create --location=C:\users\keyczar\keyset --purpose=crypt
keyczart.py addkey --location=C:\users\keyczar\keyset --status=PRIMARY

ここで気を付けなくてはならないのは --status=PRIMARY で指定する文字を大文字にする必要があることだ。マニュアルやコマンドの使い方では小文字になっているが、小文字で指定すると鍵の情報が正しく書き込まれない。たぶんバグだろう。

で、ここまで準備ができれば後は以下のように使用できる。

#!/usr/bin/env python from keyczar import keyczar crypter = keyczar.Crypter.Read(r"C:\users\keyczar\keyset…

ActionScript 3.0で使う文字だけを埋め込む

てっく煮ブログAS3で埋め込みフォントを使うテクニックで使う文字だけを埋め込む便利なスクリプトがPerlのワンライナーで書かれていたので、連続する文字に対応させてPythonで実装。

#!/usr/bin/env python # -*- coding: utf-8 -*- import sys def main(args): # 引数がなければ標準入力、あればそのファイル名から読み込み. f = file(args[1]) if len(args) > 1 else sys.stdin # 文字を読み込み、重複しないようにソートして配列に格納. letters = sorted(set([ord(s) for l in f for s in unicode(l.rstrip("\n"))])) # 小さい順に標準出力に表示. 文字コードが連続している場合は - で繋げて出力. sys.stdout.write("U+%04X" % letters[0]) pre_s = letters[0] is_seq = False for s in letters[1:]: if s - pre_s == 1: is_seq = True elif is_seq: sys.stdout.write("-U+%04X,U+%04X" % (pre_s, s)) is_seq = False else: sys.stdout.write(",U+%04X" % s) pre_s = s if is_seq: sys.stdout.write("-U+%04X" % pre_s) if __name__ == "__main__": main(sys.argv)

例えば、以下の文字を使いたい場合、

ぁぃぅぇぉ あいうえお かきくけこ abcdefg xyz

これを上記のスクリプトに通すと、

U…

Google App Engine: Googleマップのストリートビューで散歩するWebアプリ

前回のエントリでGoogle Maps APIを試しに動かしたところ問題なく動いたので、ざっとGoogle Maps APIのリファレンスを読んでみた(因みに日本語版だとストリートビュー関連のAPIがまだ載っていない)。なんとなく全体の構成が分かったところで、デモギャラリーを参考にしながら、ストリートビューを使って自由に散歩するWebアプリ、Street Strollを作ってみた。Googleマップ上のマーカーと連動して動くようにしている。また、URLのオプションでマップの大きさを自由に変えられるので環境に合わせて利用して欲しい。要望があれば、写真撮影とその保存・閲覧、位置情報保存・再開、高速移動あたりをデータストアなどを使って実装するかもしれない。

Street Stroll 400×400 (標準)
Street Stroll 300×300
Street Stroll 500×500
Street Stroll 500×250

今回もURLのオプションぐらいしかGoogle App Engineの機能を使っていないのでコードは割愛。ブラウザからソースを開けばJavaScript部分は読むことができる。

追記:

Google StrollからStreet StrollにWebアプリ名を変更した。

Google App Engine: Googleマップのストリートビューが凄い

日本でもGoogleマップでストリートビューのサービスが開始された。既にいろいろなところで話題になっているが、実際に使ってみると確かに凄い。自宅の前の道は車がぎりぎり通れるかどうかと云う細い道なのだが、それでもちゃんと自宅が写っていた。とっても面白かったので、Google Maps APIでストリートビューをいじってみたくなり、何かできないか考えてみた。

そこで、Google Maps API Demo Gallery - Lazy Street Viewを参考に、と云うかほとんどそのままのコードをGoogle App Engineで利用してみた。スクリプトをそのままHTMLとして書き出しているだけなので、Google App Engineである必要はなく、利用したというのもおこがましいのだが、Google Maps APIを一度も使ったことがなく、とりあえずどんなものか試したかっただけなのでご容赦を。でも、Google App EngineとGoogle Maps APIを組み合わせて面白そうなことができそうだなぁ。実際の町を舞台とした3Dロールプレイングゲームとか?(笑)


Google Maps Street View API Demo
デモではJR秋葉原駅とヨドバシカメラを結ぶ横断歩道を中心にカメラがぐるりと回っている。あのいつも混んでいる横断歩道だ。因みに位置を変更するには、変更したい場所をGoogleマップで検索しストリートビューを表示させ、そのリンク内の位置情報(赤字で示す)をオリジナルのスクリプトの位置情報と置き換えればよい。

http://maps.google.com/maps?f=q&hl=ja&geocode=&q=%E6%97%A5%E6%9C%AC+%E7%A7%8B%E8%91%89%E5%8E%9F&ie=UTF8&ll=35.700549,139.774622&spn=0.003929,0.006866&z=17&layer=c&cbll=35.698584,139.774216&panoid=HNw-5xoiN5NJCVEWfeSdlA&cbp=1,65.31797388218855,,0,2.5976720953303447

最後に今回使…

プログラミング言語Erlangを覚えよう

以前から関数型プログラミング言語であるErlang(アーラン)を覚えたかったので、「プログラミング言語Erlang入門」を読んだ。この本自体は本当に入門者というか初心者向けの本となっている。しかし、自分自身はほとんど関数型言語について知識がないので、こういった入門書で概略を掴めるのはありがたい。C言語などの命令型プログラミング言語と比べるとスタイルが大きく異なり、それらの知識をベースとすることができないので、先日のLuaの入門書ほどお手軽ではなかったが、内容自体は非常に簡易なので1日あれば余裕で理解できるだろう。

概略以上のことを学びたいのなら最初から「プログラミングErlang」を読むのが良い。こちらも手元にあるが、かなり良い本だと思う。ちゃんとしたプログラムを書きたいのならこちらがお勧め。

ところで、Erlangは並列処理言語としても注目を集めている。非常に効率よく並列処理ができるのが特徴で、それぞれのスレッドが完全に独立して動くように設計されている。独立しているスレッドであるためErlangではそれをプロセスと呼んでいる。spawn()関数で各プロセスを実行することができ、非常に簡単に並列処理プログラムを作ることができる。

プログラミングErlang」に内包リストを使ってアナグラムを標準出力に表示するプログラムが載っていたのだが、それを並列処理化して一つのファイルに書き出すように変更したプログラムを書いたので、このエントリの最後に示しておく。二つの文字列を二つのプロセスを使って同時にアナグラムを生成し、その結果を一つのファイルに書き出している。このコードでおぼろげながらでもErlangの雰囲気が分かるだろうか。

test.erl

-module(test). -export([perms/1, write/3, wait/1, anagram/2]). %% 順列生成. perms([]) -> [[]]; perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])]. %% ファイルへの書き出し. %% S: ファイル, L: 文字列, P: プロセス識別子. write(S, L, P) -> lists:foreach(fun(X) -> io:format…