# Copyright (C) 2009 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. __author__ = 'j.s@google.com (Jeff Scudder)' import os import wsgiref.handlers from google.appengine.api import users from google.appengine.ext import webapp from google.appengine.ext.webapp import template from google.appengine.ext.webapp.util import run_wsgi_app import gdata.gauth import gdata.data import gdata.blogger.client def get_auth_token(request): """Retrieves the AuthSub token for the current user. Will first check the request URL for a token request parameter indicating that the user has been sent to this page after authorizing the app. Auto-upgrades to a session token. If the token was not in the URL, which will usually be the case, looks for the token in the datastore. Returns: The token object if one was found for the current user. If there is no current user, it returns False, if there is a current user but no AuthSub token, it returns None. """ current_user = users.get_current_user() if current_user is None or current_user.user_id() is None: return False # Look for the token string in the current page's URL. token_string, token_scopes = gdata.gauth.auth_sub_string_from_url( request.url) if token_string is None: # Try to find a previously obtained session token. return gdata.gauth.ae_load('blogger' + current_user.user_id()) # If there was a new token in the current page's URL, convert it to # to a long lived session token and persist it to be used in future # requests. single_use_token = gdata.gauth.AuthSubToken(token_string, token_scopes) # Create a client to make the HTTP request to upgrade the single use token # to a long lived session token. client = gdata.client.GDClient() session_token = client.upgrade_token(single_use_token) gdata.gauth.ae_save(session_token, 'blogger' + current_user.user_id()) return session_token class ListBlogs(webapp.RequestHandler): """Requests the list of the user's blogs from the Blogger API.""" def get(self): template_values = { 'sign_out': users.create_logout_url('/') } # See if we have an auth token for this user. token = get_auth_token(self.request) if token is None: template_values['auth_url'] = gdata.gauth.generate_auth_sub_url( self.request.url, ['http://www.blogger.com/feeds/']) path = os.path.join(os.path.dirname(__file__), 'auth_required.html') self.response.out.write(template.render(path, template_values)) return elif token == False: self.response.out.write( '<html><body><a href="%s">You must sign in first</a>' '</body></html>' % users.create_login_url('/blogs')) return client = gdata.blogger.client.BloggerClient() feed = client.get_blogs(auth_token=token) template_values['feed'] = feed path = os.path.join(os.path.dirname(__file__), 'list_blogs.html') self.response.out.write(template.render(path, template_values)) class WritePost(webapp.RequestHandler): def get(self): template_values = { 'sign_out': users.create_logout_url('/'), 'blog_id': self.request.get('id') } # We should have an auth token for this user. token = get_auth_token(self.request) if not token: self.redirect('/blogs') return path = os.path.join(os.path.dirname(__file__), 'post_editor.html') self.response.out.write(template.render(path, template_values)) def post(self): token = get_auth_token(self.request) if not token: self.redirect('/blogs') return draft = False if self.request.get('draft') == 'true': draft = True client = gdata.blogger.client.BloggerClient() new_post = client.add_post( self.request.get('blog_id'), self.request.get('title'), self.request.get('body'), draft=draft, auth_token=token) if not draft: self.response.out.write( 'See your new post <a href="%s">here</a>.' % ( new_post.find_alternate_link())) else: self.response.out.write( 'This was a draft blog post, visit ' '<a href="http://blogger.com/">blogger.com</a> to publish') def main(): application = webapp.WSGIApplication([('/blogs', ListBlogs), ('/write_post', WritePost)], debug=True) wsgiref.handlers.CGIHandler().run(application) if __name__ == '__main__': main()