예제 #1
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def history(name):
    """Page history."""
    name = Wiki.url_to_name(name)

    # Look up the page.
    page = Wiki.get_page(name)
    if not page:
        flash("Wiki page not found.")
        return redirect(url_for(".index"))

    authors = dict()
    history = list()
    for rev in page["revisions"]:
        uid = rev["author"]
        if not uid in authors:
            authors[uid] = User.get_user(uid=uid)

        history.append(
            dict(
                id=rev["id"],
                author=authors[uid],
                note=rev["note"],
                pretty_time=pretty_time(Config.wiki.time_format, rev["time"]),
            ))

    g.info["link"] = Wiki.name_to_url(name)
    g.info["title"] = name
    g.info["history"] = history
    return template("wiki/history.html")
예제 #2
0
파일: __init__.py 프로젝트: kirsle/rophako
def history(name):
    """Page history."""
    name = Wiki.url_to_name(name)

    # Look up the page.
    page = Wiki.get_page(name)
    if not page:
        flash("Wiki page not found.")
        return redirect(url_for(".index"))

    authors = dict()
    history = list()
    for rev in page["revisions"]:
        uid = rev["author"]
        if not uid in authors:
            authors[uid] = User.get_user(uid=uid)

        history.append(
            dict(
                id=rev["id"],
                author=authors[uid],
                note=rev["note"],
                pretty_time=pretty_time(Config.wiki.time_format, rev["time"]),
            )
        )

    g.info["link"] = Wiki.name_to_url(name)
    g.info["title"] = name
    g.info["history"] = history
    return template("wiki/history.html")
예제 #3
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def entry(fid):
    """Endpoint to view a specific blog entry."""

    # Resolve the friendly ID to a real ID.
    post_id = Blog.resolve_id(fid)
    if not post_id:
        flash("That blog post wasn't found.")
        return redirect(url_for(".index"))

    # Look up the post.
    post = Blog.get_entry(post_id)
    post["post_id"] = post_id

    # Body has a snipped section?
    if "<snip>" in post["body"]:
        post["body"] = re.sub(r'\s*<snip>\s*', '\n\n', post["body"])

    # Render the body.
    if post["format"] == "markdown":
        post["rendered_body"] = render_markdown(post["body"])
    else:
        post["rendered_body"] = post["body"]

    # Render emoticons.
    if post["emoticons"]:
        post["rendered_body"] = Emoticons.render(post["rendered_body"])

    # Get the author's information.
    post["profile"] = User.get_user(uid=post["author"])
    post["photo"]   = User.get_picture(uid=post["author"])
    post["photo_url"] = Config.photo.root_public

    # Pretty-print the time.
    post["pretty_time"] = pretty_time(Config.blog.time_format, post["time"])

    # Count the comments for this post
    post["comment_count"] = Comment.count_comments("blog-{}".format(post_id))

    # Inject information about this post's siblings.
    index = Blog.get_index()
    siblings = [None, None] # previous, next
    sorted_ids = list(map(lambda y: int(y), sorted(index.keys(), key=lambda x: index[x]["time"], reverse=True)))
    for i in range(0, len(sorted_ids)):
        if sorted_ids[i] == post_id:
            # Found us!
            if i > 0:
                # We have an older post.
                siblings[0] = index[ str(sorted_ids[i-1]) ]
            if i < len(sorted_ids) - 1:
                # We have a newer post.
                siblings[1] = index[ str(sorted_ids[i+1]) ]
    post["siblings"] = siblings

    g.info["post"] = post
    return template("blog/entry.html")
예제 #4
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def preview():
    # Get the form fields.
    form = get_comment_form(request.form)
    thread = sanitize_name(form["thread"])

    # Trap fields.
    trap1 = request.form.get("website", "x") != "http://"
    trap2 = request.form.get("email", "x") != ""
    if trap1 or trap2:
        flash("Wanna try that again?")
        return redirect(url_for("index"))

    # Validate things.
    if len(form["message"]) == 0:
        flash("You must provide a message with your comment.")
        return redirect(form["url"])

    # Gravatar?
    gravatar = Comment.gravatar(form["contact"])

    # Are they submitting?
    if form["action"] == "submit":
        Comment.add_comment(
            thread=thread,
            uid=g.info["session"]["uid"],
            ip=remote_addr(),
            time=int(time.time()),
            image=gravatar,
            name=form["name"],
            subject=form["subject"],
            message=form["message"],
            url=form["url"],
        )

        # Are we subscribing to the thread?
        if form["subscribe"] == "true":
            email = form["contact"]
            if "@" in email:
                Comment.add_subscriber(thread, email)
                flash(
                    "You have been subscribed to future comments on this page."
                )

        flash("Your comment has been added!")
        return redirect(form["url"])

    # Gravatar.
    g.info["gravatar"] = gravatar
    g.info["preview"] = Comment.format_message(form["message"])
    g.info["pretty_time"] = pretty_time(Config.comment.time_format,
                                        time.time())

    g.info.update(form)
    return template("comment/preview.html")
예제 #5
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def preview():
    # Get the form fields.
    form   = get_comment_form(request.form)
    thread = sanitize_name(form["thread"])

    # Trap fields.
    trap1 = request.form.get("website", "x") != "http://"
    trap2 = request.form.get("email", "x") != ""
    if trap1 or trap2:
        flash("Wanna try that again?")
        return redirect(url_for("index"))

    # Validate things.
    if len(form["message"]) == 0:
        flash("You must provide a message with your comment.")
        return redirect(form["url"])

    # Gravatar?
    gravatar = Comment.gravatar(form["contact"])

    # Are they submitting?
    if form["action"] == "submit":
        Comment.add_comment(
            thread=thread,
            uid=g.info["session"]["uid"],
            ip=remote_addr(),
            time=int(time.time()),
            image=gravatar,
            name=form["name"],
            subject=form["subject"],
            message=form["message"],
            url=form["url"],
        )

        # Are we subscribing to the thread?
        if form["subscribe"] == "true":
            email = form["contact"]
            if "@" in email:
                Comment.add_subscriber(thread, email)
                flash("You have been subscribed to future comments on this page.")

        flash("Your comment has been added!")
        return redirect(form["url"])

    # Gravatar.
    g.info["gravatar"]    = gravatar
    g.info["preview"]     = Comment.format_message(form["message"])
    g.info["pretty_time"] = pretty_time(Config.comment.time_format, time.time())

    g.info.update(form)
    return template("comment/preview.html")
예제 #6
0
파일: __init__.py 프로젝트: kirsle/rophako
def view_page(name):
    """Show a specific wiki page."""
    link = name
    name = Wiki.url_to_name(name)

    g.info["link"] = link
    g.info["title"] = name

    # Look up the page.
    page = Wiki.get_page(name)
    if not page:
        # Page doesn't exist... yet!
        g.info["title"] = Wiki.url_to_name(name)
        return template("wiki/missing.html"), 404

    # Which revision to show?
    version = request.args.get("revision", None)
    if version:
        # Find this one.
        rev = None
        for item in page["revisions"]:
            if item["id"] == version:
                rev = item
                break

        if rev is None:
            flash("That revision was not found for this page.")
            rev = page["revisions"][0]
    else:
        # Show the latest one.
        rev = page["revisions"][0]

    # Getting the plain text source?
    if request.args.get("source", None):
        g.info["markdown"] = render_markdown(
            "\n".join(["# Source: {}".format(name), "", "```markdown", rev["body"], "```"])
        )
        return template("markdown.inc.html")

    # Render it!
    g.info["rendered_body"] = Wiki.render_page(rev["body"])
    g.info["rendered_body"] = Emoticons.render(g.info["rendered_body"])
    g.info["pretty_time"] = pretty_time(Config.wiki.time_format, rev["time"])

    # Author info
    g.info["author"] = User.get_user(uid=rev["author"])

    return template("wiki/page.html")
예제 #7
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def view_page(name):
    """Show a specific wiki page."""
    link = name
    name = Wiki.url_to_name(name)

    g.info["link"] = link
    g.info["title"] = name

    # Look up the page.
    page = Wiki.get_page(name)
    if not page:
        # Page doesn't exist... yet!
        g.info["title"] = Wiki.url_to_name(name)
        return template("wiki/missing.html"), 404

    # Which revision to show?
    version = request.args.get("revision", None)
    if version:
        # Find this one.
        rev = None
        for item in page["revisions"]:
            if item["id"] == version:
                rev = item
                break

        if rev is None:
            flash("That revision was not found for this page.")
            rev = page["revisions"][0]
    else:
        # Show the latest one.
        rev = page["revisions"][0]

    # Getting the plain text source?
    if request.args.get("source", None):
        g.info["markdown"] = render_markdown("\n".join([
            "# Source: {}".format(name), "", "```markdown", rev["body"], "```"
        ]))
        return template("markdown.inc.html")

    # Render it!
    g.info["rendered_body"] = Wiki.render_page(rev["body"])
    g.info["rendered_body"] = Emoticons.render(g.info["rendered_body"])
    g.info["pretty_time"] = pretty_time(Config.wiki.time_format, rev["time"])

    # Author info
    g.info["author"] = User.get_user(uid=rev["author"])

    return template("wiki/page.html")
예제 #8
0
파일: __init__.py 프로젝트: kirsle/rophako
def partial_index(thread, subject, header=True, addable=True):
    """Partial template for including the index view of a comment thread.

    Parameters:
        thread (str): the unique name for the comment thread.
        subject (str): subject name for the comment thread.
        header (bool): show the 'Comments' H1 header.
        addable (bool): can new comments be added to the thread?
    """

    # Get all the comments on this thread.
    comments = Comment.get_comments(thread)

    # Sort the comments by most recent on bottom.
    sorted_cids = [ x for x in sorted(comments, key=lambda y: comments[y]["time"]) ]
    sorted_comments = []
    for cid in sorted_cids:
        comment = comments[cid]
        comment["id"] = cid

        # Was the commenter logged in?
        if comment["uid"] > 0:
            user = User.get_user(uid=comment["uid"])
            avatar = User.get_picture(uid=comment["uid"])
            comment["name"] = user["name"]
            comment["username"] = user["username"]
            comment["image"] = avatar

        # Add the pretty time.
        comment["pretty_time"] = pretty_time(Config.comment.time_format, comment["time"])

        # Format the message for display.
        comment["formatted_message"] = Comment.format_message(comment["message"])

        # Was this comment posted by the current user viewing it?
        comment["editable"] = Comment.is_editable(thread, cid, comment)

        sorted_comments.append(comment)

    g.info["header"] = header
    g.info["thread"] = thread
    g.info["subject"] = subject
    g.info["commenting_disabled"] = not addable
    g.info["url"] = request.url
    g.info["comments"] = sorted_comments
    g.info["photo_url"] = Config.photo.root_public
    return template("comment/index.inc.html")
예제 #9
0
파일: __init__.py 프로젝트: kirsle/rophako
def view_photo(key):
    """View a specific photo."""
    photo = Photo.get_photo(key)
    if photo is None:
        flash("That photo wasn't found!")
        return redirect(url_for(".albums"))

    # Get the author info.
    author = User.get_user(uid=photo["author"])
    if author:
        g.info["author"] = author

    g.info["photo"] = photo
    g.info["photo"]["key"] = key
    g.info["photo"]["pretty_time"] = pretty_time(Config.photo.time_format, photo["uploaded"])
    g.info["photo"]["markdown"] = render_markdown(photo.get("description", ""))
    return template("photos/view.html")
예제 #10
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def partial_index(thread, subject, header=True, addable=True):
    """Partial template for including the index view of a comment thread.

    * thread: unique name for the comment thread
    * subject: subject name for the comment thread
    * header: show the Comments h1 header
    * addable: boolean, can new comments be added to the thread"""

    comments = Comment.get_comments(thread)

    # Sort the comments by most recent on bottom.
    sorted_cids = [
        x for x in sorted(comments, key=lambda y: comments[y]["time"])
    ]
    sorted_comments = []
    for cid in sorted_cids:
        comment = comments[cid]
        comment["id"] = cid

        # Was the commenter logged in?
        if comment["uid"] > 0:
            user = User.get_user(uid=comment["uid"])
            avatar = User.get_picture(uid=comment["uid"])
            comment["name"] = user["name"]
            comment["username"] = user["username"]
            comment["image"] = avatar

        # Add the pretty time.
        comment["pretty_time"] = pretty_time(Config.comment.time_format,
                                             comment["time"])

        # Format the message for display.
        comment["formatted_message"] = Comment.format_message(
            comment["message"])

        sorted_comments.append(comment)

    g.info["header"] = header
    g.info["thread"] = thread
    g.info["subject"] = subject
    g.info["commenting_disabled"] = not addable
    g.info["url"] = request.url
    g.info["comments"] = sorted_comments
    g.info["photo_url"] = Config.photo.root_public
    return template("comment/index.inc.html")
예제 #11
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def partial_index(thread, subject, header=True, addable=True):
    """Partial template for including the index view of a comment thread.

    * thread: unique name for the comment thread
    * subject: subject name for the comment thread
    * header: show the Comments h1 header
    * addable: boolean, can new comments be added to the thread"""

    comments = Comment.get_comments(thread)

    # Sort the comments by most recent on bottom.
    sorted_cids = [ x for x in sorted(comments, key=lambda y: comments[y]["time"]) ]
    sorted_comments = []
    for cid in sorted_cids:
        comment = comments[cid]
        comment["id"] = cid

        # Was the commenter logged in?
        if comment["uid"] > 0:
            user = User.get_user(uid=comment["uid"])
            avatar = User.get_picture(uid=comment["uid"])
            comment["name"] = user["name"]
            comment["username"] = user["username"]
            comment["image"] = avatar

        # Add the pretty time.
        comment["pretty_time"] = pretty_time(Config.comment.time_format, comment["time"])

        # Format the message for display.
        comment["formatted_message"] = Comment.format_message(comment["message"])

        sorted_comments.append(comment)

    g.info["header"] = header
    g.info["thread"] = thread
    g.info["subject"] = subject
    g.info["commenting_disabled"] = not addable
    g.info["url"] = request.url
    g.info["comments"] = sorted_comments
    g.info["photo_url"] = Config.photo.root_public
    return template("comment/index.inc.html")
예제 #12
0
파일: __init__.py 프로젝트: kirsle/rophako
def archive():
    """List all blog posts over time on one page."""
    index = Blog.get_index()

    # Group by calendar month, and keep track of friendly versions of months.
    groups = dict()
    friendly_months = dict()
    for post_id, data in index.items():
        ts = datetime.datetime.fromtimestamp(data["time"])
        date = ts.strftime("%Y-%m")
        if not date in groups:
            groups[date] = dict()
            friendly = ts.strftime("%B %Y")
            friendly_months[date] = friendly

        # Get author's profile && Pretty-print the time.
        data["profile"] = User.get_user(uid=data["author"])
        data["pretty_time"] = pretty_time(Config.blog.time_format, data["time"])
        groups[date][post_id] = data

    # Sort by calendar month.
    sort_months = sorted(groups.keys(), reverse=True)

    # Prepare the results.
    result = list()
    for month in sort_months:
        data = dict(
            month=month,
            month_friendly=friendly_months[month],
            posts=list()
        )

        # Sort the posts by time created, descending.
        for post_id in sorted(groups[month].keys(), key=lambda x: groups[month][x]["time"], reverse=True):
            data["posts"].append(groups[month][post_id])

        result.append(data)

    g.info["archive"] = result
    return template("blog/archive.html")
예제 #13
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def archive():
    """List all blog posts over time on one page."""
    index = Blog.get_index()

    # Group by calendar month, and keep track of friendly versions of months.
    groups = dict()
    friendly_months = dict()
    for post_id, data in index.items():
        ts = datetime.datetime.fromtimestamp(data["time"])
        date = ts.strftime("%Y-%m")
        if not date in groups:
            groups[date] = dict()
            friendly = ts.strftime("%B %Y")
            friendly_months[date] = friendly

        # Get author's profile && Pretty-print the time.
        data["profile"] = User.get_user(uid=data["author"])
        data["pretty_time"] = pretty_time(Config.blog.time_format, data["time"])
        groups[date][post_id] = data

    # Sort by calendar month.
    sort_months = sorted(groups.keys(), reverse=True)

    # Prepare the results.
    result = list()
    for month in sort_months:
        data = dict(
            month=month,
            month_friendly=friendly_months[month],
            posts=list()
        )

        # Sort the posts by time created, descending.
        for post_id in sorted(groups[month].keys(), key=lambda x: groups[month][x]["time"], reverse=True):
            data["posts"].append(groups[month][post_id])

        result.append(data)

    g.info["archive"] = result
    return template("blog/archive.html")
예제 #14
0
파일: __init__.py 프로젝트: kirsle/rophako
def partial_index(template_name="blog/index.inc.html", mode="normal"):
    """Partial template for including the index view of the blog.

    Args:
        template_name (str): The name of the template to be rendered.
        mode (str): The view mode of the posts, one of:
            - normal: Only list public entries, or private posts for users
                who are logged in.
            - drafts: Only list draft entries for logged-in users.
    """

    # Get the blog index.
    if mode == "normal":
        index = Blog.get_index()
    elif mode == "drafts":
        index = Blog.get_drafts()
    elif mode == "private":
        index = Blog.get_private()
    else:
        return "Invalid partial_index mode."

    # Let the pages know what mode they're in.
    g.info["mode"] = mode

    pool  = {} # The set of blog posts to show.

    category = g.info.get("url_category", None)
    if category == Config.blog.default_category:
        category = ""

    # Are we narrowing by category?
    if category is not None:
        # Narrow down the index to just those that match the category.
        for post_id, data in index.items():
            if not category in data["categories"]:
                continue
            pool[post_id] = data

        # No such category?
        if len(pool) == 0:
            flash("There are no posts with that category.")
            return redirect(url_for(".index"))
    else:
        pool = index

    # Get the posts we want.
    posts = get_index_posts(pool)

    # Handle pagination.
    offset = request.args.get("skip", 0)
    try:    offset = int(offset)
    except: offset = 0

    # Handle the offsets, and get those for the "older" and "earlier" posts.
    # "earlier" posts count down (towards index 0), "older" counts up.
    g.info["offset"]  = offset
    g.info["earlier"] = offset - int(Config.blog.entries_per_page) if offset > 0 else 0
    g.info["older"]   = offset + int(Config.blog.entries_per_page)
    if g.info["earlier"] < 0:
        g.info["earlier"] = 0
    if g.info["older"] < 0 or g.info["older"] > len(posts) - 1:
        g.info["older"] = 0
    g.info["count"] = 0

    # Can we go to other pages?
    g.info["can_earlier"] = True if offset > 0 else False
    g.info["can_older"]   = False if g.info["older"] == 0 else True

    # Load the selected posts.
    selected = []
    stop = offset + int(Config.blog.entries_per_page)
    if stop > len(posts): stop = len(posts)
    index = 1 # Let each post know its position on-page.
    for i in range(offset, stop):
        post_id = posts[i]
        post    = Blog.get_entry(post_id)

        post["post_id"] = post_id

        # Body has a snipped section?
        if "<snip>" in post["body"]:
            post["body"] = post["body"].split("<snip>")[0]
            post["snipped"] = True

        # Render the body.
        if post["format"] == "markdown":
            post["rendered_body"] = render_markdown(post["body"])
        else:
            post["rendered_body"] = post["body"]

        # Render emoticons.
        if post["emoticons"]:
            post["rendered_body"] = Emoticons.render(post["rendered_body"])

        # Get the author's information.
        post["profile"] = User.get_user(uid=post["author"])
        post["photo"]   = User.get_picture(uid=post["author"])
        post["photo_url"] = Config.photo.root_public

        post["pretty_time"] = pretty_time(Config.blog.time_format, post["time"])

        # Count the comments for this post
        post["comment_count"] = Comment.count_comments("blog-{}".format(post_id))
        post["position_index"] = index
        index += 1

        selected.append(post)
        g.info["count"] += 1

    g.info["category"] = category
    g.info["posts"] = selected

    return template(template_name)
예제 #15
0
파일: __init__.py 프로젝트: TeMbl4/rophako
def partial_index(template_name="blog/index.inc.html"):
    """Partial template for including the index view of the blog."""

    # Get the blog index.
    index = Blog.get_index()
    pool  = {} # The set of blog posts to show.

    category = g.info.get("url_category", None)
    if category == Config.blog.default_category:
        category = ""

    # Are we narrowing by category?
    if category is not None:
        # Narrow down the index to just those that match the category.
        for post_id, data in index.items():
            if not category in data["categories"]:
                continue
            pool[post_id] = data

        # No such category?
        if len(pool) == 0:
            flash("There are no posts with that category.")
            return redirect(url_for(".index"))
    else:
        pool = index

    # Get the posts we want.
    posts = get_index_posts(pool)

    # Handle pagination.
    offset = request.args.get("skip", 0)
    try:    offset = int(offset)
    except: offset = 0

    # Handle the offsets, and get those for the "older" and "earlier" posts.
    # "earlier" posts count down (towards index 0), "older" counts up.
    g.info["offset"]  = offset
    g.info["earlier"] = offset - int(Config.blog.entries_per_page) if offset > 0 else 0
    g.info["older"]   = offset + int(Config.blog.entries_per_page)
    if g.info["earlier"] < 0:
        g.info["earlier"] = 0
    if g.info["older"] < 0 or g.info["older"] > len(posts):
        g.info["older"] = 0
    g.info["count"] = 0

    # Can we go to other pages?
    g.info["can_earlier"] = True if offset > 0 else False
    g.info["can_older"]   = False if g.info["older"] == 0 else True

    # Load the selected posts.
    selected = []
    stop = offset + int(Config.blog.entries_per_page)
    if stop > len(posts): stop = len(posts)
    index = 1 # Let each post know its position on-page.
    for i in range(offset, stop):
        post_id = posts[i]
        post    = Blog.get_entry(post_id)

        post["post_id"] = post_id

        # Body has a snipped section?
        if "<snip>" in post["body"]:
            post["body"] = post["body"].split("<snip>")[0]
            post["snipped"] = True

        # Render the body.
        if post["format"] == "markdown":
            post["rendered_body"] = render_markdown(post["body"])
        else:
            post["rendered_body"] = post["body"]

        # Render emoticons.
        if post["emoticons"]:
            post["rendered_body"] = Emoticons.render(post["rendered_body"])

        # Get the author's information.
        post["profile"] = User.get_user(uid=post["author"])
        post["photo"]   = User.get_picture(uid=post["author"])
        post["photo_url"] = Config.photo.root_public

        post["pretty_time"] = pretty_time(Config.blog.time_format, post["time"])

        # Count the comments for this post
        post["comment_count"] = Comment.count_comments("blog-{}".format(post_id))
        post["position_index"] = index
        index += 1

        selected.append(post)
        g.info["count"] += 1

    g.info["category"] = category
    g.info["posts"] = selected

    return template(template_name)
예제 #16
0
파일: __init__.py 프로젝트: kirsle/rophako
def entry(fid):
    """Endpoint to view a specific blog entry."""

    # Resolve the friendly ID to a real ID.
    post_id = Blog.resolve_id(fid, drafts=True)
    if not post_id:
        # See if the friendly ID contains any extraneous dashes at the front
        # or end, and remove them and see if we have a match. This allows for
        # fixing blog fid's that allowed leading/trailing dashes and having the
        # old URL just redirect to the new one.
        fid = fid.strip("-")
        post_id = Blog.resolve_id(fid, drafts=True)

        # If still nothing, try consolidating extra dashes into one.
        if not post_id:
            fid = re.sub(r'-+', '-', fid)
            post_id = Blog.resolve_id(fid, drafts=True)

        # Did we find one now?
        if post_id:
            return redirect(url_for(".entry", fid=fid))

        flash("That blog post wasn't found.")
        return redirect(url_for(".index"))

    # Look up the post.
    post = Blog.get_entry(post_id)
    post["post_id"] = post_id

    # Body has a snipped section?
    if "<snip>" in post["body"]:
        post["body"] = re.sub(r'\s*<snip>\s*', '\n\n', post["body"])

    # Render the body.
    if post["format"] == "markdown":
        post["rendered_body"] = render_markdown(post["body"])
    else:
        post["rendered_body"] = post["body"]

    # Render emoticons.
    if post["emoticons"]:
        post["rendered_body"] = Emoticons.render(post["rendered_body"])

    # Get the author's information.
    post["profile"] = User.get_user(uid=post["author"])
    post["photo"]   = User.get_picture(uid=post["author"])
    post["photo_url"] = Config.photo.root_public

    # Pretty-print the time.
    post["pretty_time"] = pretty_time(Config.blog.time_format, post["time"])

    # Count the comments for this post
    post["comment_count"] = Comment.count_comments("blog-{}".format(post_id))

    # Inject information about this post's siblings.
    index = Blog.get_index()
    siblings = [None, None] # previous, next
    sorted_ids = list(map(lambda y: int(y), sorted(index.keys(), key=lambda x: index[x]["time"], reverse=True)))
    for i in range(0, len(sorted_ids)):
        if sorted_ids[i] == post_id:
            # Found us!
            if i > 0:
                # We have an older post.
                siblings[0] = index[ str(sorted_ids[i-1]) ]
            if i < len(sorted_ids) - 1:
                # We have a newer post.
                siblings[1] = index[ str(sorted_ids[i+1]) ]
    post["siblings"] = siblings

    g.info["post"] = post
    return template("blog/entry.html")
예제 #17
0
def track_visit(request, session):
    """Main logic to track and log visitor details."""

    # Get their tracking cookie value. The value will either be their HTTP
    # referrer (if exists and valid) or else a "1".
    cookie = session.get("tracking")
    addr = remote_addr()
    values = dict()  # Returnable traffic values

    # Log hit counts. We need four kinds:
    # - Unique today   - Unique total
    # - Hits today     - Hits total
    today = pretty_time("%Y-%m-%d", time.time())
    files = {
        "unique/{}".format(today): "unique_today",
        "unique/total": "unique_total",
        "hits/{}".format(today): "hits_today",
        "hits/total": "hits_total",
    }

    # Go through the hit count files. Update them only if their tracking
    # cookie was not present.
    for file, key in files.items():
        dbfile = "traffic/{}".format(file)
        if file.startswith("hits"):
            # Hit file is just a simple counter.
            db = dict(hits=0)
            if JsonDB.exists(dbfile):
                db = JsonDB.get(dbfile)
                if db is None:
                    db = dict(hits=0)

            # Update it?
            if not cookie:
                db["hits"] += 1
                JsonDB.commit(dbfile, db)

            # Store the copy.
            values[key] = db["hits"]
        else:
            # Unique file is a collection of IP addresses.
            db = dict()
            if JsonDB.exists(dbfile):
                db = JsonDB.get(dbfile)
                if db is None:
                    db = dict()

            # Update with their IP?
            if not cookie and not addr in db:
                db[addr] = time.time()
                JsonDB.commit(dbfile, db)

            # Store the copy.
            values[key] = len(db.keys())

    # Log their HTTP referrer.
    referrer = "1"
    if request.referrer:
        # Branch and check this.
        referrer = log_referrer(request, request.referrer)
        if not referrer:
            # Wasn't a valid referrer.
            referrer = "1"

    # Set their tracking cookie.
    if not cookie:
        cookie = referrer
        session["tracking"] = cookie

    return values