Loading...

    AD: 猛买 | 快递查询 | Jobsdigg | 很棒的男装店

动手开发一个GAE应用

可任意转载,但必须在醒目位置以超链接形式标明文章原始出处和作者信息
原文地址:http://www.blogkid.net/archives/1881.html

GAE出来有段时间了,我浏览了一下Google的App Gallery,大多数应用都侧重在客户端。当然,也有牛人开发了一个极像WP的blog应用micoblog

我想自己整一个GAE应用,用Google的服务器来保存我一个网站上的图片。现在的图片都是引用自卓越、当当,现在想保存到自己的地盘。如果能放在Google服务器上,一方面可以节约流量,另一方面也能使服务器不被一大堆小文件给拖累。毕竟有几十万个图片呐。思考一下,GAE上有urlFetch的API,完全可以满足需求。

新建一个文件夹,弄一个app.yaml的配置文件。

application: your_app_name
version: 1
runtime: python
api_version: 1

handlers:
- url: .*
script: main.py

因为需求很简单,所以用一个main.py,来处理所有请求。之后新建一个main.py。为了导入图片,需要先定义一个Photo的类(Photo这个名字其实不太合适)一个ImportHandler:

  1. from google.appengine.ext.webapp.util import run_wsgi_app
  2. from google.appengine.ext import db
  3. from google.appengine.ext import webapp
  4. from google.appengine.api import urlfetch
  5.  
  6. class ImportHandler(webapp.RequestHandler):
  7.     '''Import Pictures'''
  8.     def get(self):
  9.         global auth_code
  10.         uuid = self.request.get('uuid')
  11.         url = self.request.get('url')
  12.         result = urlfetch.fetch(url)
  13.         if result.status_code == 200:
  14.             photo = Photo.get_or_insert("uuid:"+uuid , uuid=uuid)
  15.             photo.content_type = result.headers['Content-Type']
  16.             photo.data = db.Blob(result.content)
  17.             photo.put()
  18.             self.response.out.write("SUCCESS")
  19.         else:
  20.             self.response.out.write("FAIL")
  21.  
  22. class Photo(db.Model):
  23.     uuid = db.StringProperty()
  24.     content_type = db.StringProperty(multiline=False)
  25.     data = db.BlobProperty()
  26.     date = db.DateTimeProperty(auto_now_add=True)

这样导入图片的部分就写好了。要把图片显示出来,还需要一个ViewHandler,把uuid作为参数。这里用一点小技巧,让图片的地址可以有“伪静态”的格式。比如用/view/uuid这样的格式,需要我们在webapp中定义。

  1. application = webapp.WSGIApplication([
  2.     ('/view/(?P<uuid>\w+)',ViewHandler),
  3.     ('/add' , ImportHandler)
  4.     ],debug=True)

之后定义ViewHandler:

  1. class ViewHandler(webapp.RequestHandler):
  2.     '''View A single photo'''
  3.     def get(self,uuid):
  4.         try:
  5.             photo = db.GqlQuery("select * from Photo where uuid = '"+uuid+"'").fetch(1)[0]
  6.             if photo is not None:
  7.                 self.response.headers['Content-Type'] = photo.content_type
  8.                 self.response.out.write(photo.data)
  9.                 return
  10.             else:
  11.                 return self.error(404)
  12.         except:
  13.             return self.response.out.write("ERROR")

这样当访问/view/12345的时候,会调用ViewHandler的get方法,参数就是“12345”。最后,把这些都串起来,加上下面这一段:

  1. def main():
  2.   run_wsgi_app(application)
  3.  
  4. if __name__ == "__main__":
  5.   main()

这可以算是一个最简单的APP了。用dev_appserver.py启动开发服务器,构造一个这样的地址并访问:http://localhost:8080/add?url=http://otho.douban.com/pics/logosmall.gif&uuid=douban,如果能看到success,再看一下http://localhost:8080/view/douban,豆瓣的logo就显示出来了。如果想把它部署到Google的服务器,用appcfg.py就好。

在这里还有很多可以改进,比如增加memcached缓存、增加校验码(不然别人也可以往里面写东西)、写一个可以导入内容的客户端,我会在下一篇文章里详细写写。Google的这个视频,值得看看。

BTW,好久不在blog里写大段的代码,总觉得能写清楚的东西尽量写清楚,把代码发上来让别人去读,其实是很浪费时间的事情。

4 Responses to “动手开发一个GAE应用”


  1. 我想问问 gae的开发 跟django web.py等的关系
    是因为gae支持python所以所有的python的网页框架都支持呢
    还是gae只支持什么。。

    初学者,望给予一些指导

  2. @song
    GAE有自己的限制,所以不是所有python框架都能用的。但是django是可以的

  1. [...] 乘着叶片往前飞 « 动手开发一个GAE应用 [...]

  2. [...] 动手开发一个GAE应用 八月 25, 2010 sanwuren 發表迴響 前往留言 可任意转载,但必须在醒目位置以超链接形式标明文章原始出处和作者信息 原文地址:http://www.blogkid.net/archives/1881.html [...]

Leave a Reply