text: import os
  import webapp2
  import jinja2
  import re
  import hashlib
  import hmac
  from string import letters
  import random
  import logging
  from google.appengine.ext import db
  
  # Secret password used in the hash_str function to help hash the users id.
  secret = "letmein"
  
  # This tells that all our html templates are in the folder called templates.
  # Also set up our Jinja Environment and make sure to set the autoescape html to
  # true.
  template_dir = os.path.join(os.path.dirname(__file__), 'templates')
  jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir),
                                 autoescape=True)
  
  
  # Loads the template and sends it back to render with any params.
  def render_str(template, **params):
      t = jinja_env.get_template(template)
      return t.render(params)
  
  
  # Used to Hash the users id using hmac.
  def hash_str(val):
      # return hashlib.md5(s).hexdigest()
      return hmac.new(secret, val).hexdigest()
  
  
  # Returns the user and the hashed version of the users id.
  def make_secure_val(val):
      return "%s|%s" % (val, hash_str(val))
  
  
  # The value of the cookie is sent in containing the user and the users hash.
  # It then splits out the first value, which is the users id of the cookie and
  # sends it to hash it again and if they match return the users ID from the
  # Users table.
  def check_secure_val(secure_val):
      val = secure_val.split('|')[0]
      if secure_val == make_secure_val(val):
          return val
  
  
  def login_required(func):
      """ A decorator to confirm a user is logged in or redirect them to the
      Login page if not.
      """
  
      def login(self, *args, **kwargs):
          # Redirect to login if user not logged in, else continue on with
          # the function.
          if not self.user:
              self.redirect('/login')
          else:
              func(self, *args, **kwargs)
      return login
  
  
  class Handler(webapp2.RequestHandler):
      """This class is our main webapp handleer that any of our other classes
      that call it will have access to.
      """
  
      def write(self, *a, **kw):
          self.response.out.write(*a, **kw)
  
      def render_str(self, template, **params):
          params['user'] = self.user
          return render_str(template, **params)
  
      # Sends it back to the browser.
      def render(self, template, **kw):
          self.write(self.render_str(template, **kw))
  
      # Sets the secure cookie in the browser with the users id and the hash
      # of the users id.  Set it so that it can be read at any Path.
      def set_secure_cookie(self, name, val):
          cookie_val = make_secure_val(val)
          self.response.headers.add_header(
              'Set-Cookie',
              '%s=%s; Path=/' % (name, cookie_val)
              )
  
      # Reads the Secure Cookie from the Browser's Cookie.
      def read_secure_cookie(self, name):
          cookie_val = self.request.cookies.get(name)
          return cookie_val and check_secure_val(cookie_val)
  
      # Sets the Users Cookie in the Browser, assigns the value to the
      # name user_id.
      def login(self, user):
          self.set_secure_cookie('user_id', str(user.key().id()))
  
      # When the user logs out the Secure Cookie is set back to nothing to delete
      # the cookie.  The Path=/ tells to it to look at all pages in this
      # application.
      def logout(self):
          self.response.headers.add_header('Set-Cookie', 'user_id =; Path=/')
  
      # This will read the Secure Cookie and assign it to uid and this will check
      # and see if there is a uid and if so return the User's Object by their ID.
      def initialize(self, *a, **kw):
          webapp2.RequestHandler.initialize(self, *a, **kw)
          uid = self.read_secure_cookie('user_id')
          self.user = uid and User.by_id(int(uid))
  
  
  # User stuff
  # Salt is generated by 5 random letters to be uses with verifing the password.
  # The Salt variable will be stored in the pw_hash of the User kind.
  def make_salt(length=5):
      return ''.join(random.choice(letters) for x in xrange(length))
  
  
  # Takes the User's name, the password they typed in and the value of the salt
  # and creates a password hash that will be securely stored in the User kind.
  def make_pw_hash(name, pw, salt=None):
      if not salt:
          salt = make_salt()
      h = hashlib.sha256(name + pw + salt).hexdigest()
      return '%s,%s' % (salt, h)
  
  
  # Take the User's name, their password typed in and the hash of the password,
  # if h is valid and make_pw_hash comes back valid then return the value of
  # make_pw_hash.
  def valid_pw(name, password, h):
      salt = h.split(',')[0]
      return h == make_pw_hash(name, password, salt)
  
  
  # Sets the Users key to default.  This would be useful when you want to
  # create more than one Users kind or table and you can set up a mulit-user
  # functionality to the blog or blogs.  The new Users kind will be whatever
  # value you assign to name.  In this case we are calling it 'default'.
  def users_key(group='default'):
      return db.Key.from_path('users', group)
  
  
  # Setup User Database or Entity.
  class User(db.Model):
      name = db.StringProperty(required=True)
      pw_hash = db.StringProperty(required=True)
      email = db.StringProperty()
  
  # Returns the users object identified by their ID.
      @classmethod
      def by_id(cls, uid):
          return cls.get_by_id(uid, parent=users_key())
  
  # Returns the users object identified by their user name.
      @classmethod
      def by_name(cls, name):
          u = cls.all().filter('name =', name).get()
          return u
  
  # This puts all the items together that will be added to the User table or kind
  # when a user is first created.
      @classmethod
      def register(cls, name, pw, email=None):
          pw_hash = make_pw_hash(name, pw)
          return cls(parent=users_key(),
                     name=name,
                     pw_hash=pw_hash,
                     email=email)
  
  # When logging in, a user sends ther name and password to this class method and
  # it will check and see if u is valid and then if their password is valied it
  # will return the users name.
      @classmethod
      def login(cls, name, pw):
          u = cls.by_name(name)
          if u and valid_pw(name, pw, u.pw_hash):
              return u
  
  
  # Blog Stuff
  # Sets the Blog key to default.  This would be useful when you want to
  # create more than one Blog kind or table and you can set up a mulit-blog
  # functionality.  The new Blog kind will be whatever value you assign to name.
  # In this case we are calling it 'default'.
  def blog_key(name='default'):
      return db.Key.from_path('blogs', name)
  
  
  # Defines the Post kind
  class Post(db.Model):
      """This class defines the parameters contained in the Post kind.  subject =
      the Subject of the Post.  content = the content of the Post. created = The
      current time stamp as when the Post was created.  last_modified = the
      current time stamp when the Post was modified.  creator = the Users name
      that arthored the Post. likes_user_list = contains a list of all the Users
      that clicked the like button.  This can only be clicked once by each user.
      likes_count = keeps a running total of how many unique users clicked the
      like button.
      """
  
      subject = db.StringProperty(required=True)
      content = db.TextProperty(required=True)
      created = db.DateTimeProperty(auto_now_add=True)
      last_modified = db.DateTimeProperty(auto_now=True)
      creator = db.StringProperty()
      likes_user_list = db.StringListProperty(default=None)
      likes_count = db.IntegerProperty(default=0)
  
      def render(self):
          self._render_text = self.content.replace('\n', '<br>')
          return render_str("post.html", p=self)
  
  
  # Comment Stuff
  # Sets the Comment key to default.  This would be useful when you want to
  # create more than one Comment functionality for more than one blog.
  # The new Comment kind will be whatever value you assign to name.  In this
  # case we are calling it 'default'.
  def comment_key(name='default'):
      return db.Key.from_path('comments', name)
  
  
  class Comment(db.Model):
      """ This class defines the parameters contained in the Comment kind.
      Comment is the actual comment input by the user.  The post_id is stored
      to identify which post the comment is associated with.  The comment_creator
      identies the creator of the comment.  Created gives a time stamp in the
      kind that reflects the time the entry was made.
      """
  
      comment = db.TextProperty(required=True)
      post_id = db.StringProperty(required=True)
      comment_creator = db.StringProperty()
      created = db.DateTimeProperty(auto_now_add=True)
  
  # Render the comment.html page with the object defined as c.
      def render(self):
          self._render_text = self.comment.replace('\n', '<br>')
          return render_str('comment.html', c=self)
  
  
  class LikePost(Handler):
      """This class takes a logged in user and allows them to like a post.  The
      Likes total will be printed in the subject header to the right of where the
      user that created the post is displayed.  If the user is not logged in they
      will be redirected to the login screen.  If the user is also the creator of
      the post they will get an error message.  Also if a user has already liked
      a post they can not like it muliple times, they can only like it once.
      """
  
  # The get function will first redirect the user to login if they are not
  # currently logged in.  If logged in then it will increment the likes counter
  # 'likes_count' and update it in the Post kind.  Then redirect to the main
  # Blog page.
      @login_required
      def get(self):
          post_id = self.request.get('post_id')
          post = Post.get_by_id(int(post_id), parent=blog_key())
          if (self.user.name != post.creator) and \
             (self.user.name not in post.likes_user_list):
              post.likes_user_list.append(self.user.name)
              post.likes_count += 1
              post.put()
              self.redirect('/blog')
          else:
              error = "The creator of this post cannot like their own post \
                        and a user can only like it once."
              self.render('permalink.html',
                          post=post,
                          error=error,
                          )
  
  
  # Used with the signup handler to validate a users name.  It must be at least
  # 3 and 20 characters long and be composed up letters (either small case or
  # Capital) and numbers 0 thru 9 with dashes in between.
  def valid_username(username):
      USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
      return username and USER_RE.match(username)
  
  
  # Used with the signup handler to validate a users password.  This looks for
  # a password of between 3 and 20 characters.
  def valid_password(password):
      PSWD_RE = re.compile(r"^.{3,20}$")
      return password and PSWD_RE.match(password)
  
  
  # Used with the signup handler to validate a users email address.  This looks
  # for characters followed by the @ sign followed by more characters followed
  # by a . (dot) and followed by some more characters.
  def valid_email(email):
      EMAIL_RE = re.compile(r"^[\S]+@[\S]+.[\S]+$")
      return not email or EMAIL_RE.match(email)
  
  
  class Signup(Handler):
      """This class handles the Signup up or Registration process for a new user.
      This form will prompt the user to enter a vailid User name, a valid
      Password and the user will have to verify the password by typing it twice.
      They may also enter an optional email address.
      """
  
  # This will handle the get request to render the signup form.
      def get(self):
          self.render('signup-form.html')
  
  # This will handle the Post request for the signup form.
      def post(self):
          have_error = False
          self.username = self.request.get('username')
          self.password = self.request.get('password')
          self.email = self.request.get('email')
          self.verify = self.request.get('verify')
  
          params = dict(username=self.username,
                        email=self.email)
  
          if not valid_username(self.username):
              params['error_username'] = "This is not a valid username."
              have_error = True
  
          if not valid_password(self.password):
              params['error_password'] = "This wasn't a valid password."
              have_error = True
          elif self.password != self.verify:
              params['error_verify'] = "Your passwords didn't match."
              have_error = True
  
          if not valid_email(self.email):
              params['error_email'] = "Your emial address is invalid."
              have_error = True
  
          if have_error:
              self.render('signup-form.html', **params)
  
          else:
              # Check if user is alreday in Database and if so redirect them
              # to the Welcome page.  If not then register them into the database
              # and redirect the to the welcome page.
              # Make sure the user doesn't already exist by using the u =
              # User.by_name check.  This will return the users object held in u.
              u = User.by_name(self.username)
              if u:
                  # User is already registerd and just needs to sign in
                  msg = 'That user already exists.'
                  self.render('signup-form.html', error_username=msg)
              else:
                  # everything pass all the checks so add it to the User kind
                  u = User.register(self.username, self.password, self.email)
                  u.put()
                  self.login(u)
                  # send the new user to the Welcome screen
                  self.redirect('/welcome')
  
  
  class Login(Handler):
      """This classes get request sends the user to the login page.
  
      The post request will validated the users username and password and then
      direct them to the Welcome page.
      """
  
      def get(self):
          self.render('login.html')
  
      def post(self):
          username = self.request.get('username')
          password = self.request.get('password')
  
          u = User.login(username, password)
          if u:
              self.login(u)
              self.redirect('/welcome')
          else:
              msg = 'Invlaid Login!'
              self.render('login.html', error=msg)
  
  
  class Logout(Handler):
      """This classes get request will log the user out by deleting their secure
      cookie from the browser and will then send them back to the login screen.
      """
  
      def get(self):
          self.logout()
          self.redirect('/login')
  
  
  class Welcome(Signup):
      """This classes get request will validate the user and send them to the
      welcome page otherwise it will send them to the signup page.
      """
  
      def get(self):
          username = self.user.name
          if valid_username(username):
              self.render('welcome-form.html', username=username)
          else:
              self.redirect('/signup')
  
  
  class MainBlog(Handler):
      """This class is the Main Blog handler.  When a user navigates to the Blog,
      this handler will retreive all the Post and Comments and render them on the
      blog.html page.
      """
      def get(self):
          posts = db.GqlQuery("SELECT * FROM Post ORDER BY created \
                              DESC LIMIT 10")
          comments = db.GqlQuery("SELECT * FROM Comment ORDER BY created")
          # self.render("blog.html", posts=posts, comments=comments)
          # self.render("front2.html", comments=comments)
          # self.render("front.html", posts=posts, comments=comments)
          self.render("blog.html", posts=posts, comments=comments)
  
  
  # Setup Blog Stuff
  class NewPost(Handler):
      """This class will process the NewPost Request.
  
      If the new post link was selected the get request will direct the user to
      the newpost page and if they are not signed in then they will be directed
      to the login page.
  
      The post request will handle a cancel request.  The Submit request will
      check the for a subject and content and if present will add it to the Post
      kind and direct the user to the Permalink page with the Post Id in the URL.
      If a subject and content is not entered the user is sent back to the
      newpost page along with an error message.
      """
  
      @login_required
      def get(self):
          self.render("newpost.html")
  
      @login_required
      def post(self):
          submit = self.request.get('sub')
          cancel = self.request.get('can')
  
          if cancel == 'Cancel':
              self.redirect('/blog')
  
          if submit == "Submit":
              subject = self.request.get("subject")
              content = self.request.get("content")
              creator = self.user.name
              if subject and content:
                  p = Post(parent=blog_key(),
                           subject=subject,
                           content=content,
                           creator=creator,
                           )
                  p.put()
                  last_id = p.key().id()
                  self.redirect("/blog/%d" % last_id)
              else:
                  error = "We need both a subject and some content!"
                  self.render("newpost.html",
                              subject=subject,
                              content=content,
                              error=error,
                              )
  
  
  class EditPost(Handler):
      """This class will process the Edit Post Request.
  
      If the edit post link was selected the get request will direct the user to
      the edit post page and if they are not signed into the blog they will be
      directed to the login page.  It will render the post based on the post id
      from the post that was selected.
  
      The post request will take the new subject and content and over write what
      was in the database and send the user back to the permalink page.  If the
      user happened to delete the subject or content then the page is rendered
      with an error message.
      """
  
      @login_required
      def get(self):
          post_id = self.request.get('post_id')
          post = Post.get_by_id(int(post_id), parent=blog_key())
          if not post:
              self.error(404)
              return
          subject = post.subject
          content = post.content
          creator = post.creator
          if self.user.name == creator:
              self.render('editpost.html',
                          subject=subject,
                          content=content,
                          creator=creator,
                          )
          else:
              error = "Sorry! You must be the author of this post in order \
                       to edit it."
              self.render('permalink.html',
                          subject=subject,
                          content=content,
                          error=error,
                          post=post,
                          )
  
      @login_required
      def post(self):
          post_id = self.request.get('post_id')
          subject = self.request.get('subject')
          content = self.request.get('content')
          submit = self.request.get('sub')
          cancel = self.request.get('can')
  
          if cancel == 'Cancel':
              self.redirect('/blog')
  
          if submit == "Submit":
              post = Post.get_by_id(int(post_id), parent=blog_key())
              if not post:
                  self.error(404)
                  return
              creator = post.creator
              if self.user.name == creator:
                  if subject and content:
                      post.subject = subject
                      post.content = content
                      post.put()
                      last_id = post.key().id()
                      self.redirect("/blog/%d" % last_id)
                  else:
                      error = "You must enter both a subject and content."
                      self.render('editpost.html',
                                  subject=subject,
                                  content=content,
                                  error=error,
                                  )
  
  
  class DeletePost(Handler):
      """This class will process the Delete Post Request.
  
      If the delete post link was selected the get request will direct the user
      to the delete post page and if they are not signed into the blog they will
      be directed to the login page.  It will render the post based on the post
      id from the post that was selected. This will also check to make sure the
      user requesting to delete it is also the creator of it and if not they will
      be directed back to the delete page with an error message.
  
      The post request will check that the user is the creator and if so delete
      the post otherwise will be directed back to the delete page with an error
      message.  The user sill also have a cancel option.
      """
  
      @login_required
      def get(self):
          post_id = self.request.get('post_id')
          post_id = int(post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          if not post:
              self.error(404)
              return
          if self.user.name == post.creator:
              self.render('deletepost.html',
                          subject=post.subject,
                          content=post.content,
                          creator=post.creator,
                          )
          else:
              error = "You must be the author of this post in order to \
                       delete it."
              self.render('deletepost.html',
                          subject=post.subject,
                          content=post.content,
                          creator=post.creator,
                          error=error,
                          )
  
      @login_required
      def post(self):
          post_id = self.request.get('post_id')
          confirmed = self.request.get('del')
          cancel = self.request.get('can')
          post_id = int(post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          if not post:
              self.error(404)
              return
          if cancel == 'Cancel':
              self.redirect('/blog')
  
          if confirmed == 'Delete':
              if self.user.name == post.creator:
                  post.delete()
                  self.redirect('/blog')
              else:
                  error = "You must be the author of this post in order to \
                           delete it. Please hit the Cancel button to return \
                           to the Blog."
                  self.render('deletepost.html',
                              subject=post.subject,
                              content=post.content,
                              creator=post.creator,
                              error=error,
                              )
  
  
  class NewComment(Handler):
      """This class will process the NewComment Request.
  
      If the Add a comment link was selected the get request will direct the user
      to the new comment page and if they are not signed into then they will be
      directed to the login page.
  
      The post request will handle a cancel request.  When the submit button is
      selected it will check the for a comment and if present will add it to the
      Comment kind and direct the user back to the Blog.  If a comment is not
      entered the user is sent back to the new comment page along with an
      error message.
      """
  
      @login_required
      def get(self):
              self.render_comment()
  
      def render_comment(self, comment="", error=""):
          post_id = self.request.get('post_id')
          post_id = int(post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          if not post:
              self.error(404)
              return
          self.render("comment-new.html",
                      subject=post.subject,
                      content=post.content,
                      comment=comment,
                      post_id=post_id,
                      )
  
      @login_required
      def post(self):
          # Get the cancel indicator and if user hit the Cancel button then
          # return to the main blog.
          cancel = self.request.get('can')
          if cancel == 'Cancel':
              self.redirect('/blog')
          else:
              # If the Submit button was selected then the following is executed.
              comment = self.request.get("comment")
              post_id = self.request.get('post_id')
              post_id = int(post_id)
              post = Post.get_by_id(post_id, parent=blog_key())
              if not post:
                  self.error(404)
                  return
              if comment:
                  c = Comment(parent=comment_key(),
                              comment=comment,
                              post_id=str(post_id),
                              comment_creator=self.user.name,
                              )
                  c.put()
                  last_id = c.key().id()
                  self.redirect("/blog")
              else:
                  error = "Sorry! You must enter a comment to continue.  Or hit \
                           cancel to return back to the blog."
                  self.render("comment-new.html",
                              subject=post.subject,
                              content=post.content,
                              comment=comment,
                              post_id=post_id,
                              error=error,
                              )
  
  
  class EditComment(Handler):
      """This class will process the Edit Comment Request.
  
      If the edit comment link was selected the get request will direct the user
      to the edit comment page and if they are not signed into the blog they will
      be directed to the login page.  It will render the post content along with
      the comment content.
  
      The post request will take the new comment and over write what
      was in the database and send the user back to the blog page.  If the user
      happened to delete the comment and left that field blank then the page is
      rendered with an error message.  It will also check to make sure that the
      user making the edit is the original creator of the comment and if not
      direct them to the page with an error message.
      """
  
      @login_required
      def get(self):
          comment_id = self.request.get('comment_id')
          if not comment_id:
              self.redirect('/login')
              return
          comment_id = int(comment_id)
          comment = Comment.get_by_id(comment_id, parent=comment_key())
          if not comment:
              self.error(404)
              return
          post_id = int(comment.post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          if self.user.name == comment.comment_creator:
              self.render('comment-edit.html',
                          comment=comment.comment,
                          creator=comment.comment_creator,
                          post_id=post_id,
                          comment_id=comment_id,
                          subject=post.subject,
                          content=post.content,
                          )
          else:
              error = "You must be the author of this comment in order to \
                       edit it."
              self.render('comment-edit.html',
                          comment=comment.comment,
                          creator=comment.comment_creator,
                          subject=post.subject,
                          content=post.content,
                          post_id=post_id,
                          error=error,
                          )
  
      @login_required
      def post(self):
          comment_id = self.request.get('comment_id')
          edit_comment = self.request.get('comment')
          confirmed = self.request.get('sub')
          cancel = self.request.get('can')
          comment_id = int(comment_id)
          comment = Comment.get_by_id(comment_id, parent=comment_key())
          if not comment:
              self.error(404)
              return
          post_id = int(comment.post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          # If the Cancel button is selected return back to the blog.
          if cancel == 'Cancel':
              self.redirect('/blog')
          # Otherwise continue on with processing the comment to either add it to
          # the comment database and if no comment was enered then send the user
          # back to the comment page and ask them to input a comment.
          if self.user.name == comment.comment_creator:
              if edit_comment:
                  if confirmed == 'Submit':
                      self.redirect('/blog')
                      comment.comment = edit_comment
                      comment.put()
                      self.redirect('/blog')
              else:
                  # If the user happens to delete the contents of comments on
                  # the form then they will be directed back to this error with
                  # a post request.
                  error = "You must enter a comment to continue and the comment \
                           box can not be blank."
                  self.render('comment-edit.html',
                              comment=comment.comment,
                              creator=comment.comment_creator,
                              subject=post.subject,
                              content=post.content,
                              post_id=post_id,
                              error=error,
                              )
          else:
              # If the user choose the Submit botton after the first error
              # message was displayed they will be directed to this error message
              # until the cancel button is selected or a valid comment is
              # entered.
              error = "Sorry!!! You must be the author of this comment in order \
                       to edit it.  Please return to the main Blog or hit \
                       the Cancel button to continue."
              self.render('comment-edit.html',
                          comment=comment.comment,
                          creator=comment.comment_creator,
                          subject=post.subject,
                          content=post.content,
                          post_id=post_id,
                          error=error,
                          )
  
  
  class DeleteComment(Handler):
      """This class will process the Delete Comment Request.
  
      If the delete comment link was selected the get request will direct the
      user to the delete comment page and if they are not signed into the blog
      they will be directed to the login page.  It will render the post and
      comment data on the delete comment form.  This will also check to make sure
      the user requesting to delete it is also the creator of it and if not they
      will be directed back to the delete comment page with an error message.
  
      The post request will perform a double check that the user is the creator
      and if so delete the comment otherwise will be directed back to the delete
      page with a second error message.  The user sill also have a cancel
      option.
      """
  
      @login_required
      def get(self):
          # if the user selects the delete comment option then display the
          # post with the comment that is about to be deleted and ask the
          # user to confirm they want to really delete this particular comment
          # before it is deleted.
          comment_id = self.request.get('comment_id')
          comment_id = int(comment_id)
          comment = Comment.get_by_id(comment_id, parent=comment_key())
          if not comment:
              self.error(404)
              return
          post_id = int(comment.post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          if self.user.name == comment.comment_creator:
              self.render('comment-delete.html',
                          comment=comment.comment,
                          subject=post.subject,
                          content=post.content,
                          )
          else:
              error = "You must be the author of this comment in order to \
                       delete it."
              self.render('comment-delete.html',
                          comment=comment.comment,
                          subject=post.subject,
                          content=post.content,
                          error=error,
                          )
  
      @login_required
      def post(self):
          # First check to see if the Cancel button was selected and if so return
          # the user back to the Blog.
          cancel = self.request.get('can')
          if cancel == 'Cancel':
              self.redirect('/blog')
  
          # Otherwise continue on with the deletion of the comment.
          comment_id = self.request.get('comment_id')
          confirmed = self.request.get('del')
          comment_id = int(comment_id)
          comment = Comment.get_by_id(comment_id, parent=comment_key())
          if not comment:
              self.error(404)
              return
          post_id = int(comment.post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          if self.user.name == comment.comment_creator:
              if confirmed == 'Delete':
                  comment.delete()
                  self.redirect('/blog')
          else:
              # If the user hit the delete button and not the author of the
              # comment they will be redirected to this screen with an updated
              # error message until they hit the cancel button or choose to
              # return back to the main blog.
              error = "Sorry!!! You must be the author of this comment in order \
                       to delete it.  Please return to the main Blog or hit \
                       the Cancel button to continue."
              self.render('comment-delete.html',
                          comment=comment.comment,
                          subject=post.subject,
                          content=post.content,
                          error=error,
                          )
  
  
  class PermaLink(Handler):
      """This class will direct the user to a Permalink page upon successful
      completion of entering a new post.  This Permalink page will render the
      content of the new post.
      """
  
      def get(self, post_id):
          post_id = int(post_id)
          post = Post.get_by_id(post_id, parent=blog_key())
          self.render("permalink.html", post=post)
  
  # The following web app will contain all the handlers used in this Blog
  # application.
  app = webapp2.WSGIApplication([('/', MainBlog),
                                 ('blog/?', MainBlog),
                                 ('/signup', Signup),
                                 ('/login', Login),
                                 ('/logout', Logout),
                                 ('/welcome', Welcome),
                                 ('/blog', MainBlog),
                                 ('/blog/newpost', NewPost),
                                 ('/blog/permalink', PermaLink),
                                 (r'/blog/(\d+)', PermaLink),
                                 ('/editpost', EditPost),
                                 ('/deletepost', DeletePost),
                                 ('/comment-new', NewComment),
                                 ('/comment-delete', DeleteComment),
                                 ('/comment-edit', EditComment),
                                 ('/likepost', LikePost)
                                 ],
                                debug=True)
  