update to reflect API changes
[gae-samples.git] / muvmuv / main.py
blob8c432dc1e83f4f1103cd02192f82cfd4d475551d
1 import os
2 import md5
3 import re
4 import urllib
5 import datetime
6 import math
8 import simplejson
10 # Different versions of ElementTree can exist in different locations depending
11 # on the installed Python version.
12 try:
13 from xml.etree.cElementTree import *
14 except ImportError:
15 try:
16 from xml.etree.ElementTree import *
17 except ImportError:
18 from elementtree.ElementTree import *
20 from google.appengine.api import urlfetch
21 from google.appengine.api import users
22 from google.appengine.ext import webapp
23 from google.appengine.ext.webapp import template
24 from google.appengine.ext.webapp.util import run_wsgi_app
25 from google.appengine.ext import db
27 MONTHS = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
30 class MainPage(webapp.RequestHandler):
31 def get(self):
33 user = users.get_current_user()
34 login = users.create_login_url(self.request.uri)
35 logout = users.create_logout_url(self.request.uri)
37 template_file_name = 'mainpage.html'
38 template_values = {'login': login, 'logout': logout, 'user': user}
40 path = os.path.join(os.path.dirname(__file__), template_file_name)
41 self.response.out.write(template.render(path, template_values))
44 class ReviewPage(webapp.RequestHandler):
45 def get(self):
46 user = users.get_current_user()
47 login = users.create_login_url(self.request.uri)
48 logout = users.create_logout_url(self.request.uri)
50 template_file_name = 'reviewpage.html'
51 template_values = {'login': login, 'logout': logout, 'user': user}
53 path = os.path.join(os.path.dirname(__file__), template_file_name)
54 self.response.out.write(template.render(path, template_values))
57 class SubmitReview(webapp.RequestHandler):
58 def post(self):
59 json = self.request.get('json')
61 json = simplejson.loads(json)
63 movie_review = MovieReview()
64 movie_review.comment = json['reviewComment']
65 movie_review.title = json['title']
66 movie_review.movie = getMovie(movie_review.title)
67 movie_review.author = users.get_current_user()
69 movie_review.put()
72 class Movie(db.Model):
73 title = db.StringProperty()
74 picture = db.BlobProperty(default=None)
75 full_content = db.TextProperty(default=None)
76 summary = db.TextProperty(default=None)
77 date = db.DateTimeProperty(auto_now_add=True)
78 release_date = db.DateTimeProperty(default=None)
79 rating_average = db.FloatProperty(default=0.0)
80 rating_count = db.IntegerProperty(default=0)
83 class MovieReview(db.Model):
84 title = db.StringProperty()
85 movie = db.Reference(Movie)
86 author = db.UserProperty()
87 comment = db.TextProperty()
88 date = db.DateTimeProperty(auto_now_add=True)
91 class GetImage(webapp.RequestHandler):
93 def get(self):
95 title = self.request.get('title')
97 movie = getMovie(title)
99 if (movie and movie.picture):
100 self.response.headers['Content-Type'] = 'image/jpg'
101 self.response.out.write(movie.picture)
102 else:
103 self.redirect('/static/noimage.jpg')
106 class SetRating(webapp.RequestHandler):
107 def post(self):
108 title =self.request.get('title')
109 rating = float(self.request.get('rating'))
110 movie = getMovie(title)
111 movie.rating_average = (movie.rating_average * movie.rating_count +
112 rating) / (movie.rating_count + 1)
113 movie.rating_count = movie.rating_count + 1
114 movie.put()
117 class GetReviewsJson(webapp.RequestHandler):
118 def get(self):
120 title = self.request.get('title')
121 movie = getMovie(title)
122 json_obj = {}
124 json_obj['movie'] = {}
125 json_obj['reviews'] = []
127 json_obj['movie']['title'] = movie.title
128 json_obj['movie']['summary'] = movie.summary
129 json_obj['movie']['release_date'] = movie.release_date.ctime()
130 json_obj['movie']['pic'] = 'image?' + urllib.urlencode({'title': movie.title})
131 json_obj['movie']['rating_average'] = movie.rating_average
132 json_obj['movie']['rating_count'] = movie.rating_count
134 results = db.GqlQuery("SELECT * FROM MovieReview WHERE title = :1 ORDER BY date ASC",
135 title)
137 for result in results:
138 review = {}
139 review['title'] = result.title
140 review['author'] = result.author.nickname()
141 review['comment'] = result.comment
142 review['date'] = result.date.ctime()
144 json_obj['reviews'].append(review)
146 json_str = simplejson.dumps(json_obj)
148 self.response.headers['Content-Type'] = 'text/javascript'
149 self.response.out.write(json_str)
152 class GetMoviesJson(webapp.RequestHandler):
153 def get(self):
154 sortby = self.request.get('sortby')
155 page = self.request.get('page')
157 if (not sortby):
158 sortby = 'release_date'
160 if (not page):
161 page = 1
162 else:
163 page = int(page)
165 results = db.GqlQuery("SELECT * FROM Movie ORDER BY %s ASC" % sortby)
167 item_per_page = 16
169 start_index = (page - 1) * item_per_page
171 total_items = results.count()
173 results = results.fetch(item_per_page, start_index)
175 json_obj = {}
177 json_obj['total'] = total_items
179 json_obj['movies'] = []
181 for result in results:
182 movie = {}
183 movie['title'] = result.title
184 #movie['summary'] = result.summary
185 movie['release_date'] = result.release_date.ctime()
186 movie['pic'] = 'image?' + urllib.urlencode({'title': result.title})
189 json_obj['movies'].append(movie)
191 json_str = simplejson.dumps(json_obj)
193 self.response.headers['Content-Type'] = 'text/javascript'
194 self.response.out.write(json_str)
197 def getMovie(title):
198 result = db.GqlQuery("SELECT * FROM Movie WHERE title = :1 LIMIT 1",
199 title).fetch(1)
201 if (len(result) > 0):
202 return result[0]
203 else:
204 return None
207 class DeleteAll(webapp.RequestHandler):
208 def get(self):
209 results = db.GqlQuery("SELECT * FROM Movie")
210 for result in results:
211 result.delete()
212 results = db.GqlQuery("SELECT * FROM MovieReview")
213 for result in results:
214 result.delete()
217 class Build(webapp.RequestHandler):
219 def get(self):
221 build_only = self.request.get('buildonly')
223 if (not build_only):
224 build_only = False
225 else:
226 build_only = True
228 rss1 = 'http://movies.go.com/xml/rss/intheaters.xml'
229 rss2 = 'http://movies.go.com/xml/rss/upcoming.xml'
231 movies = self.getMoviesFromRss(rss1, build_only)
233 new_movies = movies['new']
234 update_movies = movies['update']
236 movies = self.getMoviesFromRss(rss2, build_only)
238 new_movies.extend(movies['new'])
239 update_movies.extend(movies['update'])
241 self.response.headers['Content-Type'] = 'text/html'
242 self.response.out.write('added %d new movie(s)<br>' % (len(new_movies),))
243 self.response.out.write(str(new_movies) + '<br><br>')
244 self.response.out.write('updated %d existing movie(s)<br>' % (len(update_movies),))
245 self.response.out.write(str(update_movies) + '<br>')
247 def getMoviesFromRss(self, url, build_only=False):
249 rss = urlfetch.Fetch(url)
251 tree = ElementTree(fromstring(rss.content))
253 img_re = re.compile('<img src="([a-zA-Z0-9/:._\-]+)" ')
254 content_re = re.compile('&#0151; \n(.+)')
256 release_re = re.compile('Release:</strong> ([a-zA-Z]{3,4})\. ([0-9]{1,2}), ([0-9]{4})')
258 new_movies = []
259 update_movies = []
261 for item in tree.findall('.//item'):
262 title = item.find('title').text.strip()
264 is_new = True
266 movie = getMovie(title)
268 if (not movie):
269 movie = Movie()
270 else:
271 is_new = False
272 if (build_only):
273 continue
275 description = item.find('description').text.strip()
276 summary = (content_re.search(description)).groups()[0]
278 release_match = (release_re.search(description))
280 imageMatch = img_re.search(description)
282 movie.title = title
283 movie.full_content = description
284 movie.summary = db.Text(summary)
286 if (release_match):
287 release_month = MONTHS.index(release_match.groups()[0].upper()) + 1
288 release_date = int(release_match.groups()[1])
289 release_year = int(release_match.groups()[2])
291 movie.release_date = datetime.datetime(release_year, release_month, release_date)
293 if (imageMatch):
294 picture_url = imageMatch.groups()[0]
295 movie.picture = db.Blob(urlfetch.Fetch(picture_url).content)
297 movie.put()
299 if (is_new):
300 new_movies.append(title)
301 else:
302 update_movies.append(title)
304 movies = {}
305 movies['new'] = new_movies
306 movies['update'] = update_movies
308 return movies
311 class Test(webapp.RequestHandler):
312 def get(self):
313 title = self.request.get('title')
314 movie = getMovie(title)
315 if (not movie):
316 title = 'None'
317 else:
318 title = movie.title
319 self.response.headers['Content-Type'] = 'text/html'
320 self.response.out.write('Movie title: %s' % title)
321 self.response.out.write('<br/>')
324 apps_binding = []
326 apps_binding.append(('/', MainPage))
327 apps_binding.append(('/test', Test))
328 apps_binding.append(('/review', ReviewPage))
329 apps_binding.append(('/reviews', GetReviewsJson))
330 apps_binding.append(('/movies', GetMoviesJson))
331 apps_binding.append(('/image', GetImage))
332 apps_binding.append(('/submitreview', SubmitReview))
333 apps_binding.append(('/deleteall', DeleteAll))
334 apps_binding.append(('/build', Build))
335 apps_binding.append(('/rating', SetRating))
337 application = webapp.WSGIApplication(apps_binding, debug=True)
340 def main():
341 run_wsgi_app(application)
344 if __name__ == '__main__':
345 main()