update to reflect API changes
[gae-samples.git] / images-demo / images_demo.py
blob3f7dc0d17015f5b2caddf299d5014a7733cce1d0
1 #!/usr/bin/python2.5
3 # Copyright 2008 Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
18 """Demo for the Google App Engine images API.
20 Provides a simple way to apply transforms to canned images.
22 This file contains all request handlers.
23 """
25 import os
26 import urllib
27 import wsgiref.handlers
29 from google.appengine.api import images
30 from google.appengine.ext import webapp
31 from google.appengine.ext.webapp import template
33 import image_transformer
36 class TemplatedPage(webapp.RequestHandler):
37 """Base class for templatized handlers."""
39 def write_template(self, values):
40 """Write out the template with the same name as the class name."""
41 path = os.path.join(os.path.dirname(__file__), 'templates',
42 self.__class__.__name__ + '.html')
43 self.response.out.write(template.render(path, values))
46 class MainPage(TemplatedPage):
47 """Request handler for main index page."""
49 def get(self):
50 """Handle GET request."""
51 imagelist = os.listdir(os.path.join(os.path.dirname(__file__), 'samples'))
53 values = {
54 'imagelist': imagelist,
55 'title': 'App Engine Image Demo'
58 self.write_template(values)
61 class ImagePage(TemplatedPage):
62 """Request handler for image information display page."""
64 def get(self):
65 """Handle GET request."""
66 image = self.request.get('image')
67 if not image:
68 # TODO: More friendly error.
69 self.error(400)
70 return
72 # Transformer is used here only to validate parameters.
73 transformer = image_transformer.ImageTransformer(self.request.params,
74 images.JPEG)
75 transformer.unknown_params.remove('image')
76 # format is not really a transform.
77 while 'format' in transformer.unknown_params:
78 transformer.unknown_params.remove('format')
80 transform_args = urllib.urlencode(transformer.transforms).replace('%2C',',')
81 if (self.request.get('format') == 'png'
82 or self.request.get('format') == 'jpeg'):
83 transform_args += '&format=%s' % (self.request.get('format'))
85 documentation = {}
86 for (method, _) in image_transformer.VALID_TRANSFORMS.iteritems():
87 documentation[method] = getattr(images.Image, method).__doc__
89 values = {
90 'documentation': documentation,
91 'image': image,
92 'title': 'App Engine Image Demo',
93 'transformer': transformer,
94 'transform_args': transform_args,
97 self.write_template(values)
100 class SamplePage(TemplatedPage):
101 """Request handler for image transform sample page."""
103 def get(self):
104 """Handle GET request."""
105 image = self.request.get('image')
106 if not image:
107 # TODO: More friendly error.
108 self.error(400)
109 return
111 transform_list = [
112 'resize=200,200',
113 'im_feeling_lucky&resize=200,200',
114 'rotate=90&resize=200,200',
115 'rotate=180&resize=200,200',
116 'rotate=360&resize=200,200',
117 'resize=50,50',
118 'resize=50,50&resize=200,200',
119 'resize=200,200&crop=0.0,0.0,0.5,0.5',
120 'crop=0.5,0.0,1.0,0.5&resize=200,200',
121 'horizontal_flip&resize=200,200',
122 'vertical_flip&resize=200,200',
125 values = {
126 'image': image,
127 'title': 'App Engine Image Demo',
128 'transform_list': transform_list,
130 self.write_template(values)
133 class ViewSource(TemplatedPage):
134 """Page handler for view source page."""
136 def get(self):
137 """Handle GET request.
139 An extremely simple implementation of view source using a template.
141 files = ['images_demo.py', 'image_transformer.py']
142 file_contents = []
143 for filename in files:
144 f = open(filename, 'r')
145 file_contents += [{'name': filename,
146 'contents': f.read()}]
147 f.close()
149 values = {
150 'filecontents': file_contents,
151 'title': 'App Engine Image Demo Source Code',
153 self.write_template(values)
156 class ImageData(webapp.RequestHandler):
157 """Request handler for image binary data output."""
159 def load_local_sample_image(self, filename):
160 """Load a sample image from a (local to this script) filename."""
161 path = os.path.join(os.path.dirname(__file__), 'samples', filename)
162 f = open(path, 'rb')
163 data = f.read()
164 f.close()
165 return data
167 def get(self):
168 """Handle image data GET."""
169 image = self.request.get('image')
170 if not image:
171 # TODO: More friendly error.
172 self.error(400)
173 return
175 format = images.JPEG
176 if self.request.get('format') == 'png':
177 format = images.PNG
179 data = self.load_local_sample_image(image)
181 transformer = image_transformer.ImageTransformer(self.request.params,
182 format)
183 data = transformer.transform_image(data)
185 if format == images.PNG:
186 self.response.headers['Content-Type'] = 'image/png'
187 else:
188 self.response.headers['Content-Type'] = 'image/jpeg'
190 self.response.out.write(data)
193 def main():
194 application = webapp.WSGIApplication([('/', MainPage),
195 ('/tryit', ImagePage),
196 ('/imagedata', ImageData),
197 ('/sample', SamplePage),
198 ('/viewsource', ViewSource),
200 debug=True)
201 wsgiref.handlers.CGIHandler().run(application)
203 if __name__ == '__main__':
204 main()