Example #1
0
    errors['email_error'] = ""

    if not USER_RE.match(username):
        errors['username_error'] = ("invalid username. " +
                                    "try just letters and numbers")
        return False

    if not PASS_RE.match(password):
        errors['password_error'] = "invalid password."
        return False
    if password != verify:
        errors['verify_error'] = "password must match"
        return False
    if email != "":
        if not EMAIL_RE.match(email):
            errors['email_error'] = "invalid email address"
            return False
    return True


connection_string = "mongodb://localhost"
connection = pymongo.MongoClient(connection_string)
database = connection.blog

posts = blogPostDAO.BlogPostDAO(database)
users = userDAO.UserDAO(database)
sessions = sessionDAO.SessionDAO(database)

bottle.debug(True)
bottle.run(host='localhost', port=8082)  # Start the webserver, listens
Example #2
0
def blog_index():

    cookie = bottle.request.get_cookie("session")

    username = sessions.get_username(cookie)

    # even if there is no logged in user, we can show the blog
    l = posts.get_posts(10)

    return bottle.template('blog_template', dict(myposts=l, username=username))

    # Displays a particular blog post
    @bottle.get("/post/<permalink>")
    def show_post(permalink="notfound"):

        cookie = bottle.request.get_cookie("session")

        username = sessions.get_username(cookie)
        permalink = cgi.escape(permalink)

        print "about to query on permalink = ", permalink
        post = posts.get_post_by_permalink(permalink)

        if post is None:
            bottle.redirect("/post_not_found")

        # init comment form fields for additional comment
        comment = {'name': "", 'body': "", 'email': ""}

        return bottle.template(
            "entry_template",
            dict(post=post, username=username, errors="", comment=comment))

    # used to process a comment on a blog post
    @bottle.post('/newcomment')
    def post_new_comment():
        name = bottle.request.forms.get("commentName")
        email = bottle.request.forms.get("commentEmail")
        body = bottle.request.forms.get("commentBody")
        permalink = bottle.request.forms.get("permalink")

        post = posts.get_post_by_permalink(permalink)
        cookie = bottle.request.get_cookie("session")

        username = sessions.get_username(cookie)

        # if post not found, redirect to post not found error
        if post is None:
            bottle.redirect("/post_not_found")
            return

        # if values not good, redirect to view with errors

        if name == "" or body == "":
            # user did not fill in enough information

            # init comment for web form
            comment = {'name': name, 'email': email, 'body': body}

            errors = "Post must contain your name and an actual comment."
            return bottle.template(
                "entry_template",
                dict(post=post,
                     username=username,
                     errors=errors,
                     comment=comment))

        else:

            # it all looks good, insert the comment into the blog post and redirect back to the post viewer
            posts.add_comment(permalink, name, email, body)

            bottle.redirect("/post/" + permalink)

    @bottle.get("/post_not_found")
    def post_not_found():
        return "Sorry, post not found"

    # Displays the form allowing a user to add a new post. Only works for logged in users
    @bottle.get('/newpost')
    def get_newpost():

        cookie = bottle.request.get_cookie("session")
        username = sessions.get_username(cookie)  # see if user is logged in
        if username is None:
            bottle.redirect("/login")

        return bottle.template(
            "newpost_template",
            dict(subject="", body="", errors="", tags="", username=username))

    #
    # Post handler for setting up a new post.
    # Only works for logged in user.

    @bottle.post('/newpost')
    def post_newpost():
        title = bottle.request.forms.get("subject")
        post = bottle.request.forms.get("body")
        tags = bottle.request.forms.get("tags")

        cookie = bottle.request.get_cookie("session")
        username = sessions.get_username(cookie)  # see if user is logged in
        if username is None:
            bottle.redirect("/login")

        if title == "" or post == "":
            errors = "Post must contain a title and blog entry"
            return bottle.template(
                "newpost_template",
                dict(subject=cgi.escape(title, quote=True),
                     username=username,
                     body=cgi.escape(post, quote=True),
                     tags=tags,
                     errors=errors))

        # extract tags
        tags = cgi.escape(tags)
        tags_array = extract_tags(tags)

        # looks like a good entry, insert it escaped
        escaped_post = cgi.escape(post, quote=True)

        # substitute some <p> for the paragraph breaks
        newline = re.compile('\r?\n')
        formatted_post = newline.sub("<p>", escaped_post)

        permalink = posts.insert_entry(title, formatted_post, tags_array,
                                       username)

        # now bottle.redirect to the blog permalink
        bottle.redirect("/post/" + permalink)

    # displays the initial blog signup form
    @bottle.get('/signup')
    def present_signup():
        return bottle.template(
            "signup",
            dict(username="",
                 password="",
                 password_error="",
                 email="",
                 username_error="",
                 email_error="",
                 verify_error=""))

    # displays the initial blog login form

    @bottle.get('/login')
    def present_login():
        return bottle.template("login",
                               dict(username="", password="", login_error=""))

    # handles a login request

    @bottle.post('/login')
    def process_login():

        username = bottle.request.forms.get("username")
        password = bottle.request.forms.get("password")

        print "user submitted ", username, "pass ", password

        user_record = users.validate_login(username, password)
        if user_record:
            # username is stored in the user collection in the _id key
            session_id = sessions.start_session(user_record['_id'])

            if session_id is None:
                bottle.redirect("/internal_error")

            cookie = session_id

            # Warning, if you are running into a problem whereby the cookie being set here is
            # not getting set on the redirect, you are probably using the experimental version of bottle (.12).
            # revert to .11 to solve the problem.
            bottle.response.set_cookie("session", cookie)

            bottle.redirect("/welcome")

        else:
            return bottle.template(
                "login",
                dict(username=cgi.escape(username),
                     password="",
                     login_error="Invalid Login"))

    @bottle.get('/internal_error')
    @bottle.view('error_template')
    def present_internal_error():
        return {'error': "System has encountered a DB error"}

    @bottle.get('/logout')
    def process_logout():

        cookie = bottle.request.get_cookie("session")

        sessions.end_session(cookie)

        bottle.response.set_cookie("session", "")

        bottle.redirect("/signup")

    @bottle.post('/signup')
    def process_signup():

        email = bottle.request.forms.get("email")
        username = bottle.request.forms.get("username")
        password = bottle.request.forms.get("password")
        verify = bottle.request.forms.get("verify")

        # set these up in case we have an error case
        errors = {'username': cgi.escape(username), 'email': cgi.escape(email)}
        if validate_signup(username, password, verify, email, errors):

            if not users.add_user(username, password, email):
                # this was a duplicate
                errors[
                    'username_error'] = "Username already in use. Please choose another"
                return bottle.template("signup", errors)

            session_id = sessions.start_session(username)
            print session_id
            bottle.response.set_cookie("session", session_id)
            bottle.redirect("/welcome")
        else:
            print "user did not validate"
            return bottle.template("signup", errors)

    @bottle.get("/welcome")
    def present_welcome():
        # check for a cookie, if present, then extract value

        cookie = bottle.request.get_cookie("session")
        username = sessions.get_username(cookie)  # see if user is logged in
        if username is None:
            print "welcome: can't identify user...redirecting to signup"
            bottle.redirect("/signup")

        return bottle.template("welcome", {'username': username})

    def extract_tags(tags):

        whitespace = re.compile('\s')

        nowhite = whitespace.sub("", tags)
        tags_array = nowhite.split(',')

        # let's clean it up
        cleaned = []
        for tag in tags_array:
            if tag not in cleaned and tag != "":
                cleaned.append(tag)

        return cleaned

    # validates that the user information is valid for new signup, return True of False
    # and fills in the error string if there is an issue
    def validate_signup(username, password, verify, email, errors):
        USER_RE = re.compile(r"^[a-zA-Z0-9_-]{3,20}$")
        PASS_RE = re.compile(r"^.{3,20}$")
        EMAIL_RE = re.compile(r"^[\S]+@[\S]+\.[\S]+$")

        errors['username_error'] = ""
        errors['password_error'] = ""
        errors['verify_error'] = ""
        errors['email_error'] = ""

        if not USER_RE.match(username):
            errors[
                'username_error'] = "invalid username. try just letters and numbers"
            return False

        if not PASS_RE.match(password):
            errors['password_error'] = "invalid password."
            return False
        if password != verify:
            errors['verify_error'] = "password must match"
            return False
        if email != "":
            if not EMAIL_RE.match(email):
                errors['email_error'] = "invalid email address"
                return False
        return True

    connection_string = "mongodb://localhost"
    connection = pymongo.MongoClient(connection_string)
    database = connection.blogging

    posts = blogPostDAO.BlogPostDAO(database)
    users = userDAO.UserDAO(database)
    sessions = sessionDAO.SessionDAO(database)