2008/04/09

Recent entries from same category

  1. Google App EngineでZIPファイル内に存在するファイルに対してリクエストハンドラ制御が出来る様になった Hatena
  2. Growl for Windowsで日本語が表示出来た Hatena
  3. Google App Engine Oilが素晴らしい Hatena
  4. Google App Engineで作れるアプリ数が3個から10個に増えた Hatena
  5. ゆの in Python Hatena

はてな
Google App Engineを弄り始めています。
昨日はGoogle App EngineにXMLパーサが入っていない(実際にはpyexptが入っていない)為、python版のWebService::Simpleが動きませんでしたが、PyWrapperを使う事で解決する事が分かりました。結構知れれていないと思いますので、実は結構有益情報かもしれません。
PyWrapper - Trac
これはすごい!

さっそく昨日作ったpython版WebService::Simple「webSimple」を改良し
  • google.appengine.api.urlfetchがimport出来るならばfetchを使用
  • elementtree.SimpleXMLTreeBuilderがimport出来るならTreeBuilderを使用
となる様にしました。
そしてflickr検索のコードは以下の様になりました。
api = Simple({
    'base_url' : 'http://api.flickr.com/services/rest',
    'param' : {
        'api_key' : 'your-api-key'
    },
})
res = api.get({
    'method'   : 'flickr.photos.search',
    'text'     : keyword.encode('utf-8', 'replace'),
    'per_page' : 3,
});
print res.parse_xml().find("photos").getchildren()
あとは、WSGIApplicationに仕立てる為に以下の様なテンプレートを用意します。

flickr.html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>flickr画像検索</title>
    </head>
    <body>
        <form method="post">
            <input type="text" name="keyword" value="{{ keyword }}" />
            <input type="submit" />
        </form>
        <div id="content"></div>
        {% for e in photos %}
        <a href="http://www.flickr.com/photos/{{ e.attrib.owner }}/{{ e.attrib.id }}/">
            <img src="http://static.flickr.com/{{ e.attrib.server }}/{{ e.attrib.id }}_{{ e.attrib.secret }}_m.jpg" title="{{ e.attrib.title }}" />
        </a>
        <br />{% endfor %}
        <!--
        <pre>{{ content|escape }}</pre>
        -->
    </body>
</html>
さらに以下の様なハンドラを書きます。

flickr.py
#!-*- coding:utf-8 -*-
import os
import cgi
import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from webSimple import Simple

class MainPage(webapp.RequestHandler):
  def post(self):
    keyword = cgi.escape(self.request.get('keyword'))
    api = Simple({
        'base_url' : 'http://api.flickr.com/services/rest',
        'param' : {
            'api_key' : 'your-api-key'
        },
    })
    res = api.get({
        'method'   : 'flickr.photos.search',
        'text'     : keyword.encode('utf-8', 'replace'),
        'per_page' : 3,
    });
    path = os.path.join(os.path.dirname(__file__), 'flickr.html')
    photos = []
    template_values = {
        'keyword' : keyword,
        'photos'  : res.parse_xml().find("photos").getchildren(),
        #'photos'  : [],
        'content' : res.content,
    }
    self.response.out.write(template.render(path, template_values))

  def get(self):
    path = os.path.join(os.path.dirname(__file__), 'flickr.html')
    self.response.out.write(template.render(path, {}))

def main():
  application = webapp.WSGIApplication([('/flickr/', MainPage)], debug=True)
  wsgiref.handlers.CGIHandler().run(application)

最後に「dev_appserver.py」で動作確認し、「appcfg.py」で更新したら出来上がり。
flickr検索ページが出来上がりました。現状は写真3枚までしか検索出来ないようにしてあります。
flickr画像検索

なお、ディレクトリ構造は
─mattn
  │  flickr.html
  │  flickr.py
  │  webSimple.py
  │  
  └─elementtree
          ElementInclude.py
          ElementPath.py
          ElementPath.pyc
          ElementTree.py
          ElementTree.pyc
          HTMLTreeBuilder.py
          SgmlopXMLTreeBuilder.py
          SimpleXMLTreeBuilder.py
          SimpleXMLTreeBuilder.pyc
          SimpleXMLWriter.py
          TidyHTMLTreeBuilder.py
          TidyTools.py
          XMLTreeBuilder.py
          __init__.py
          __init__.pyc
となっており、elementtreeはPyWrapperから部分的に使用しています。
またwebSimpleのコードはcodereposに上げておきますので、興味のある方は見てください。
/lang/python/webSimple/webSimple.py - CodeRepos::Share - Trac

I love python!

WriteBacks

Google/AppEngine

http://code.google.com/intl/ja/appengine/ Python URLؤΥˤURL FetchȤ Big Sky :: Google App EngineXMLѡˡ(pythonWebService::SimpleȤäflickr)

Posted by assari (PukiWiki/TrackBack 0.3) at 2008/08/29 (Fri) 06:44:42

TrackBack ping me at
Post a comment

writeback message: Ready to post a comment.