10 # Different versions of ElementTree can exist in different locations depending
11 # on the installed Python version.
13 from xml
.etree
.cElementTree
import *
16 from xml
.etree
.ElementTree
import *
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
):
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
):
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
):
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()
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
):
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
)
103 self
.redirect('/static/noimage.jpg')
106 class SetRating(webapp
.RequestHandler
):
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
117 class GetReviewsJson(webapp
.RequestHandler
):
120 title
= self
.request
.get('title')
121 movie
= getMovie(title
)
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",
137 for result
in results
:
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
):
154 sortby
= self
.request
.get('sortby')
155 page
= self
.request
.get('page')
158 sortby
= 'release_date'
165 results
= db
.GqlQuery("SELECT * FROM Movie ORDER BY %s ASC" % sortby
)
169 start_index
= (page
- 1) * item_per_page
171 total_items
= results
.count()
173 results
= results
.fetch(item_per_page
, start_index
)
177 json_obj
['total'] = total_items
179 json_obj
['movies'] = []
181 for result
in results
:
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
)
198 result
= db
.GqlQuery("SELECT * FROM Movie WHERE title = :1 LIMIT 1",
201 if (len(result
) > 0):
207 class DeleteAll(webapp
.RequestHandler
):
209 results
= db
.GqlQuery("SELECT * FROM Movie")
210 for result
in results
:
212 results
= db
.GqlQuery("SELECT * FROM MovieReview")
213 for result
in results
:
217 class Build(webapp
.RequestHandler
):
221 build_only
= self
.request
.get('buildonly')
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('— \n(.+)')
256 release_re
= re
.compile('Release:</strong> ([a-zA-Z]{3,4})\. ([0-9]{1,2}), ([0-9]{4})')
261 for item
in tree
.findall('.//item'):
262 title
= item
.find('title').text
.strip()
266 movie
= getMovie(title
)
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
)
283 movie
.full_content
= description
284 movie
.summary
= db
.Text(summary
)
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
)
294 picture_url
= imageMatch
.groups()[0]
295 movie
.picture
= db
.Blob(urlfetch
.Fetch(picture_url
).content
)
300 new_movies
.append(title
)
302 update_movies
.append(title
)
305 movies
['new'] = new_movies
306 movies
['update'] = update_movies
311 class Test(webapp
.RequestHandler
):
313 title
= self
.request
.get('title')
314 movie
= getMovie(title
)
319 self
.response
.headers
['Content-Type'] = 'text/html'
320 self
.response
.out
.write('Movie title: %s' % title
)
321 self
.response
.out
.write('<br/>')
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)
341 run_wsgi_app(application
)
344 if __name__
== '__main__':