読者です 読者をやめる 読者になる 読者になる

不動産屋のラノベ読み

不動産売買営業だけどガチガチの賃貸派の人のブログ

不動産屋の俺がGoogle App EngineでAPIもどきを作る件_01

 
 連載予定。
 素人の私が使うのを見れば、参考になる人もいるかな、という企画意図。だから、プログラマの人には役に立たないです。つーか、恥ずかしいです。
 GAEはプログラマじゃなくても全然面白いので、みんな使いませんか?*1
 

Lhankor_Mhyのスペック
  • プログラミング業務経験なし
  • Pythonは初めて使う
  • JavaScriptは多少習熟している、かも、という程度

 

作るもの

 http://【アプリ名】.appspot.com/resize/http://example.com/hoge.jpg?fit=100x100にアクセスするとhttp://example.com/hoge.jpgを100×100に収まるようにリサイズするAPIもどき
 

開始

とりあえず、URLを抜き出す

 ドキュメントを見ながらapp.yamlを変更

handlers:
- url: /resize.*
  script: resize.py

 resize.pyは以下のように。

class MainHandler(webapp.RequestHandler):

  def get(self, rURL):
    self.response.out.write(rURL)
  
    
def main():
  application = webapp.WSGIApplication(
                                       [
                                       (r'/(.*)', MainHandler)
                                       ],
                                       debug=True)
  wsgiref.handlers.CGIHandler().run(application)


if __name__ == '__main__':
  main()

 いきなり動かない。いろいろ試した挙句、resize.pyを以下のようにする。

(r'/(.*)', MainHandler)

 ↓

(r'/resize/(.*)', MainHandler)

 動いた。ルートから書かないといけないらしい。
 "http%3A//example.com/hoge.jpg"と返ってくる。コロンはエンコードされるらしい。次。
 

URLにアクセスする
class MainHandler(webapp.RequestHandler):

  def get(self, rURL):
    result = urlfetch.fetch(rURL)
    if result.status_code == 200:
      self.response.out.write(result.content)

 動かない。InvalidURLErrorだそう。コロンがエンコードされているのを忘れてた。

    result = urlfetch.fetch(rURL)

    result = urlfetch.fetch( urllib.unquote(rURL) )

 "import urllib"を忘れて一回失敗したが、http://localhost:8080/resize/http://example.com/にアクセスしたら、http://example.com/と同じように表示された、成功。日本語のページにいくと文字化けする事があったが、あまり気にしないでおく。次。
 

画像をリサイズしてみる
def get(self, rURL):
  result = urlfetch.fetch( urllib.unquote(rURL) )
  if result.status_code == 200:
    img = images.Image(result.content)
    img.resize(width=100, height=100)
    resData = img.execute_transforms(output_encoding=images.JPEG)
    self.response.headers["Content-Type"] = "image/jpeg"
    self.response.out.write(resData)

 はてなフォトライフの写真を適当に引っ張ってくると、一発成功。ひゃっほう。
 しかし、何故か100×100にならない。いろいろ試したがアスペクト比を変えないで収まるようにリサイズするみたい。やることが一つ減ってうれしいが、それで困ることもありそうな。
 

URLパラメタでサイズを受け取る。
def get(self, rURL):
  sizeX, sizeY = self.request.get('fit').split('x',2)
  result = urlfetch.fetch( urllib.unquote(rURL) )
  if result.status_code == 200:
    img = images.Image(result.content)
    img.resize(width=int(sizeX), height=int(sizeX))
    resData = img.execute_transforms(output_encoding=images.JPEG)
    self.response.headers["Content-Type"] = "image/jpeg"
    self.response.out.write(resData)

 オライリー本を睨みながら、アンパック代入とやらを試してみた。Pythonはおしゃれだなー。
 で、成功。
 というか、とりあえず目標の要件を満たしてしまった。ここまで1時間程度。簡単すぎる、恐ろしい。
 
 ついでにエラー処理などもしてみる。

try :
  sizeX, sizeY = map( (lambda x:int(x)), self.request.get('fit').split('x',2) )
except :
  sizeX, sizeY = [150, 150]

 パラメタがダメな感じのときは、150×150にしてしまうことにした。めんどくさいし。
 あと。jQuery.mapみたいなのあるかなー、と思って探したらやっぱりあったので使う。これは便利。オライリー本に「ラムダ式を使え」と書いてあったので使う。これはスマート。
 

つづく

 やっぱり内部にキャッシュぐらいはしたい、のでやる。
不動産屋の俺がGoogle App EngineでAPIもどきを作る件_02 - 不動産屋のラノベ読み
 
 

*1:逆にプログラマの人のほうがいろいろ不満が出るんじゃないかな