コード例 #1
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")
コード例 #2
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")
コード例 #3
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def edit_album(album):
    photos = Photo.list_photos(album)
    if photos is None:
        flash("That album doesn't exist.")
        return redirect(url_for(".albums"))

    if request.method == "POST":
        # Collect the form details.
        new_name    = request.form["name"]
        description = request.form["description"]
        layout      = request.form["format"]

        # Renaming the album?
        if new_name != album:
            ok = Photo.rename_album(album, new_name)
            if not ok:
                flash("Failed to rename album: already exists?")
                return redirect(url_for(".edit_album", album=album))
            album = new_name

        # Update album settings.
        Photo.edit_album(album, dict(
            description=description,
            format=layout,
        ))

        return redirect(url_for(".albums"))

    g.info["album"] = album
    g.info["album_info"] = Photo.get_album(album)
    g.info["photos"] = photos

    return template("photos/edit_album.html")
コード例 #4
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def edit(thread, cid):
    """Edit an existing comment."""
    url = request.args.get("url")
    comment = Comment.get_comment(thread, cid)
    if not comment:
        flash("The comment wasn't found!")
        return redirect(url or url_for("index"))

    # Submitting?
    if request.method == "POST":
        action  = request.form.get("action")
        message = request.form.get("message")
        url     = request.form.get("url") # Preserve the URL!
        if len(message) == 0:
            flash("The comment must have a message!")
            return redirect(url_for(".edit", thread=thread, cid=cid, url=url))

        # Update the real comment data with the submitted message (for preview),
        # if they clicked Save it will then be saved back to disk.
        comment["message"] = message

        if action == "save":
            # Saving the changes!
            Comment.update_comment(thread, cid, comment)
            flash("Comment updated successfully!")
            return redirect(url or url_for("index"))

    # Render the Markdown.
    comment["formatted_message"] = Comment.format_message(comment["message"])

    g.info["thread"]  = thread
    g.info["cid"]     = cid
    g.info["comment"] = comment
    g.info["url"]     = url or ""
    return template("comment/edit.html")
コード例 #5
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def list_pages():
    """Wiki page list."""
    g.info["pages"] = [
        {"name": name, "link": Wiki.name_to_url(name)} \
            for name in Wiki.list_pages()
    ]
    return template("wiki/list.html")
コード例 #6
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")
コード例 #7
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def crop(photo):
    pic = Photo.get_photo(photo)
    if not pic:
        flash("The photo you want to crop wasn't found!")
        return redirect(url_for(".albums"))

    # Saving?
    if request.method == "POST":
        try:
            x      = int(request.form.get("x", 0))
            y      = int(request.form.get("y", 0))
            length = int(request.form.get("length", 0))
        except:
            flash("Error with form inputs.")
            return redirect(url_for(".crop", photo=photo))

        # Re-crop the photo!
        Photo.crop_photo(photo, x, y, length)
        flash("The photo has been cropped!")
        return redirect(url_for(".albums")) # TODO go to photo

    # Get the photo's true size.
    true_width, true_height = Photo.get_image_dimensions(pic)
    g.info["true_width"] = true_width
    g.info["true_height"] = true_height
    g.info["photo"] = photo
    g.info["preview"] = pic["large"]
    return template("photos/crop.html")
コード例 #8
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def unsubscribe():
    """Unsubscribe an e-mail from a comment thread (or all threads)."""

    # This endpoint can be called with either method. For the unsubscribe links
    # inside the e-mails, it uses GET. For the global out-opt, it uses POST.
    thread, email = None, None
    if request.method == "POST":
        thread = request.form.get("thread", "")
        email = request.form.get("email", "")

        # Spam check.
        trap1 = request.form.get("url", "x") != "http://"
        trap2 = request.form.get("message", "x") != ""
        if trap1 or trap2:
            flash("Wanna try that again?")
            return redirect(url_for("index"))
    else:
        thread = request.args.get("thread", "")
        email = request.args.get("who", "")

    # Input validation.
    if not thread:
        flash("Comment thread not found.")
        return redirect(url_for("index"))
    if not email:
        flash("E-mail address not provided.")
        return redirect(url_for("index"))

    # Do the unsubscribe. If thread is *, this means a global unsubscribe from
    # all threads.
    Comment.unsubscribe(thread, email)

    g.info["thread"] = thread
    g.info["email"] = email
    return template("comment/unsubscribed.html")
コード例 #9
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def unsubscribe():
    """Unsubscribe an e-mail from a comment thread (or all threads)."""

    # This endpoint can be called with either method. For the unsubscribe links
    # inside the e-mails, it uses GET. For the global out-opt, it uses POST.
    thread, email = None, None
    if request.method == "POST":
        thread = request.form.get("thread", "")
        email  = request.form.get("email", "")

        # Spam check.
        trap1 = request.form.get("url", "x") != "http://"
        trap2 = request.form.get("message", "x") != ""
        if trap1 or trap2:
            flash("Wanna try that again?")
            return redirect(url_for("index"))
    else:
        thread = request.args.get("thread", "")
        email  = request.args.get("who", "")

    # Input validation.
    if not thread:
        flash("Comment thread not found.")
        return redirect(url_for("index"))
    if not email:
        flash("E-mail address not provided.")
        return redirect(url_for("index"))

    # Do the unsubscribe. If thread is *, this means a global unsubscribe from
    # all threads.
    Comment.unsubscribe(thread, email)

    g.info["thread"] = thread
    g.info["email"]  = email
    return template("comment/unsubscribed.html")
コード例 #10
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def login():
    """Log into an account."""

    if request.method == "POST":
        username = request.form.get("username", "")
        password = request.form.get("password", "")

        # Lowercase the username.
        username = username.lower()

        if User.check_auth(username, password):
            # OK!
            db = User.get_user(username=username)
            session["login"] = True
            session["username"] = username
            session["uid"]  = db["uid"]
            session["name"] = db["name"]
            session["role"] = db["role"]

            # Redirect them to a local page?
            url = request.form.get("url", "")
            if url.startswith("/"):
                return redirect(url)

            return redirect(url_for("index"))
        else:
            flash("Authentication failed.")
            return redirect(url_for(".login"))

    return template("account/login.html")
コード例 #11
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def edit(thread, cid):
    """Edit an existing comment."""
    url = request.args.get("url")
    comment = Comment.get_comment(thread, cid)
    if not comment:
        flash("The comment wasn't found!")
        return redirect(url or url_for("index"))

    # Submitting?
    if request.method == "POST":
        action = request.form.get("action")
        message = request.form.get("message")
        url = request.form.get("url")  # Preserve the URL!
        if len(message) == 0:
            flash("The comment must have a message!")
            return redirect(url_for(".edit", thread=thread, cid=cid, url=url))

        # Update the real comment data with the submitted message (for preview),
        # if they clicked Save it will then be saved back to disk.
        comment["message"] = message

        if action == "save":
            # Saving the changes!
            Comment.update_comment(thread, cid, comment)
            flash("Comment updated successfully!")
            return redirect(url or url_for("index"))

    # Render the Markdown.
    comment["formatted_message"] = Comment.format_message(comment["message"])

    g.info["thread"] = thread
    g.info["cid"] = cid
    g.info["comment"] = comment
    g.info["url"] = url or ""
    return template("comment/edit.html")
コード例 #12
0
def login():
    """Log into an account."""

    if request.method == "POST":
        username = request.form.get("username", "")
        password = request.form.get("password", "")

        # Lowercase the username.
        username = username.lower()

        if User.check_auth(username, password):
            # OK!
            db = User.get_user(username=username)
            session["login"] = True
            session["username"] = username
            session["uid"] = db["uid"]
            session["name"] = db["name"]
            session["role"] = db["role"]

            # Redirect them to a local page?
            url = request.form.get("url", "")
            if url.startswith("/"):
                return redirect(url)

            return redirect(url_for("index"))
        else:
            flash("Authentication failed.")
            return redirect(url_for(".login"))

    return template("account/login.html")
コード例 #13
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")
コード例 #14
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def edit_user(uid):
    uid = int(uid)
    user = User.get_user(uid=uid)

    # Submitting?
    if request.method == "POST":
        action = request.form.get("action", "")
        username = request.form.get("username", "")
        name = request.form.get("name", "")
        pw1 = request.form.get("password1", "")
        pw2 = request.form.get("password2", "")
        role = request.form.get("role", "")

        username = username.lower()

        if action == "save":
            # Validate...
            errors = None

            # Don't allow them to change the username to one that exists.
            if username != user["username"]:
                if User.exists(username=username):
                    flash("That username already exists.")
                    return redirect(url_for(".edit_user", uid=uid))

            # Password provided?
            if len(pw1) > 0:
                errors = validate_create_form(username, pw1, pw2)
            elif username != user["username"]:
                # Just validate the username, then.
                errors = validate_create_form(username, skip_passwd=True)

            if errors:
                for error in errors:
                    flash(error)
                return redirect(url_for(".edit_user", uid=uid))

            # Update the user.
            user["username"] = username
            user["name"] = name or username
            user["role"] = role
            if len(pw1) > 0:
                user["password"] = User.hash_password(pw1)
            User.update_user(uid, user)

            flash("User account updated!")
            return redirect(url_for(".users"))

        elif action == "delete":
            # Don't let them delete themself!
            if uid == g.info["session"]["uid"]:
                flash("You shouldn't delete yourself!")
                return redirect(url_for(".edit_user", uid=uid))

            User.delete_user(uid)
            flash("User deleted!")
            return redirect(url_for(".users"))

    return template("admin/edit_user.html", info=user)
コード例 #15
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def users():
    # Get the list of existing users.
    users = User.list_users()

    return template(
        "admin/users.html",
        users=users,
    )
コード例 #16
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def edit():
    """Wiki page editor."""
    title = request.args.get("name", "")
    body = ""
    history = True  # Update History box is always checked by default
    note = request.args.get("note", "")

    # Editing an existing page?
    page = Wiki.get_page(title)
    if page:
        head = page["revisions"][0]
        body = head["body"]

    if request.method == "POST":
        # Submitting the form.
        action = request.form.get("action", "preview")
        title = request.form.get("name", "")
        body = request.form.get("body", "")
        history = request.form.get("history", "false") == "true"
        note = request.form.get("note", "")

        if action == "preview":
            # Just previewing it.
            g.info["preview"] = True

            # Render markdown
            g.info["rendered_body"] = Wiki.render_page(body)

            # Render emoticons.
            g.info["rendered_body"] = Emoticons.render(g.info["rendered_body"])
        elif action == "publish":
            # Publishing! Validate inputs.
            invalid = False

            if len(title) == 0:
                invalid = True
                flash("You must have a page title.")
            if len(body) == 0:
                invalid = True
                flash("You must have a page body.")

            if not invalid:
                # Update the page.
                Wiki.edit_page(
                    author=g.info["session"]["uid"],
                    name=title,
                    body=body,
                    note=note,
                    history=history,
                )
                return redirect(
                    url_for("wiki.view_page", name=Wiki.name_to_url(title)))

    g.info["title"] = title
    g.info["body"] = body
    g.info["note"] = note
    g.info["history"] = history
    return template("wiki/edit.html")
コード例 #17
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def upload():
    """Upload a photo."""

    if request.method == "POST":
        # We're posting the upload.

        # Is this an ajax post or a direct post?
        is_ajax = request.form.get("__ajax", "false") == "true"

        # Album name.
        album = request.form.get("album") or request.form.get("new-album")

        # What source is the pic from?
        result = None
        location = request.form.get("location")
        if location == "pc":
            # An upload from the PC.
            result = Photo.upload_from_pc(request)
        elif location == "www":
            # An upload from the Internet.
            result = Photo.upload_from_www(request.form)
        else:
            flash("Stop messing around.")
            return redirect(url_for(".upload"))

        # How'd it go?
        if result["success"] is not True:
            if is_ajax:
                return ajax_response(False, result["error"])
            else:
                flash("The upload has failed: {}".format(result["error"]))
                return redirect(url_for(".upload"))

        # Good!
        if is_ajax:
            # Was it a multiple upload?
            if result.get("multi"):
                return ajax_response(True, url_for(".album_index", name=album))
            else:
                return ajax_response(True, url_for(".crop", photo=result["photo"]))
        else:
            if result["multi"]:
                return redirect(url_for(".album_index", name=album))
            else:
                return redirect(url_for(".crop", photo=result["photo"]))

    # Get the list of available albums.
    g.info["album_list"] = [
        "My Photos", # the default
    ]
    g.info["selected"] = Config.photo.default_album
    albums = Photo.list_albums()
    if len(albums):
        g.info["album_list"] = [ x["name"] for x in albums ]
        g.info["selected"] = albums[0]

    return template("photos/upload.html")
コード例 #18
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def albums():
    """View the index of the photo albums."""
    albums = Photo.list_albums()

    # If there's only one album, jump directly to that one.
    if len(albums) == 1:
        return redirect(url_for(".album_index", name=albums[0]["name"]))

    g.info["albums"] = albums
    return template("photos/albums.html")
コード例 #19
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")
コード例 #20
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")
コード例 #21
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")
コード例 #22
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def edit():
    """Wiki page editor."""
    title = request.args.get("name", "")
    body = ""
    history = True  # Update History box is always checked by default
    note = request.args.get("note", "")

    # Editing an existing page?
    page = Wiki.get_page(title)
    if page:
        head = page["revisions"][0]
        body = head["body"]

    if request.method == "POST":
        # Submitting the form.
        action = request.form.get("action", "preview")
        title = request.form.get("name", "")
        body = request.form.get("body", "")
        history = request.form.get("history", "false") == "true"
        note = request.form.get("note", "")

        if action == "preview":
            # Just previewing it.
            g.info["preview"] = True

            # Render markdown
            g.info["rendered_body"] = Wiki.render_page(body)

            # Render emoticons.
            g.info["rendered_body"] = Emoticons.render(g.info["rendered_body"])
        elif action == "publish":
            # Publishing! Validate inputs.
            invalid = False

            if len(title) == 0:
                invalid = True
                flash("You must have a page title.")
            if len(body) == 0:
                invalid = True
                flash("You must have a page body.")

            if not invalid:
                # Update the page.
                Wiki.edit_page(author=g.info["session"]["uid"], name=title, body=body, note=note, history=history)
                return redirect(url_for("wiki.view_page", name=Wiki.name_to_url(title)))

    g.info["title"] = title
    g.info["body"] = body
    g.info["note"] = note
    g.info["history"] = history
    return template("wiki/edit.html")
コード例 #23
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def delete_revision(name, revision):
    """Delete a wiki page revision from history."""
    link = name
    name = Wiki.url_to_name(name)

    if request.method == "POST":
        Wiki.delete_history(name, revision)
        flash("Revision deleted.")
        return redirect(url_for("wiki.view_page", name=Wiki.name_to_url(name)))

    g.info["confirm_url"] = url_for("wiki.delete_revision", name=link, revision=revision)
    g.info["title"] = name
    g.info["type"] = "revision"
    return template("wiki/delete.html")
コード例 #24
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def delete_page(name):
    """Delete a wiki page entirely."""
    link = name
    name = Wiki.url_to_name(name)

    if request.method == "POST":
        Wiki.delete_page(name)
        flash("Page completely deleted.")
        return redirect(url_for("wiki.index"))

    g.info["confirm_url"] = url_for("wiki.delete_page", name=link)
    g.info["title"] = name
    g.info["type"] = "page"
    return template("wiki/delete.html")
コード例 #25
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def delete_page(name):
    """Delete a wiki page entirely."""
    link = name
    name = Wiki.url_to_name(name)

    if request.method == "POST":
        Wiki.delete_page(name)
        flash("Page completely deleted.")
        return redirect(url_for("wiki.index"))

    g.info["confirm_url"] = url_for("wiki.delete_page", name=link)
    g.info["title"] = name
    g.info["type"] = "page"
    return template("wiki/delete.html")
コード例 #26
0
def index():
    """List the available emoticons."""
    theme = Emoticons.load_theme()

    smileys = []
    for img in sorted(theme["map"]):
        smileys.append({
            "img": img,
            "triggers": theme["map"][img],
        })

    g.info["theme"] = Config.emoticons.theme
    g.info["theme_name"] = theme["name"]
    g.info["smileys"]    = smileys
    return template("emoticons/index.html")
コード例 #27
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def arrange_albums():
    """Rearrange the photo album order."""
    albums = Photo.list_albums()
    if len(albums) == 0:
        flash("There are no albums yet.")
        return redirect(url_for(".albums"))

    if request.method == "POST":
        order = request.form.get("order", "").split(";")
        Photo.order_albums(order)
        flash("The albums have been rearranged!")
        return redirect(url_for(".albums"))

    g.info["albums"] = albums
    return template("photos/arrange_albums.html")
コード例 #28
0
def referrers():
    g.info["referrers"] = Tracking.get_referrers()

    # Filter some of the links.
    for i, link in enumerate(g.info["referrers"]["referrers"]):
        # Clean up useless Google links.
        if "google" in link[0] and re.search(
                r'/(?:imgres|url|search|translate\w+)?/', link[0]):
            g.info["referrers"]["referrers"][i] = None

    # Make the links word-wrap properly.
    filtered = [[re.sub(r'(.{20})', r'\1<wbr>', x[0]), x[1]]
                for x in g.info["referrers"]["referrers"] if x is not None]
    g.info["referrers"]["referrers"] = filtered

    return template("tracking/referrers.html")
コード例 #29
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def delete_revision(name, revision):
    """Delete a wiki page revision from history."""
    link = name
    name = Wiki.url_to_name(name)

    if request.method == "POST":
        Wiki.delete_history(name, revision)
        flash("Revision deleted.")
        return redirect(url_for("wiki.view_page", name=Wiki.name_to_url(name)))

    g.info["confirm_url"] = url_for("wiki.delete_revision",
                                    name=link,
                                    revision=revision)
    g.info["title"] = name
    g.info["type"] = "revision"
    return template("wiki/delete.html")
コード例 #30
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def arrange_photos(album):
    """Rearrange the photos in an album."""
    photos = Photo.list_photos(album)
    if photos is None:
        flash("That album doesn't exist.")
        return redirect(url_for(".albums"))

    if request.method == "POST":
        order = request.form.get("order", "").split(";")
        Photo.order_photos(album, order)
        flash("The albums have been rearranged!")
        return redirect(url_for(".album_index", name=album))

    g.info["album"]  = album
    g.info["photos"] = photos
    return template("photos/arrange_photos.html")
コード例 #31
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")
コード例 #32
0
def legacy_download():
    form = None
    if request.method == "POST":
        form = request.form
    else:
        # CNET links to the MS-DOS download using semicolon delimiters in the
        # query string. Fix that if detected.
        query = request.query_string.decode()
        if not '&' in query and ';' in query:
            url = re.sub(r';|%3b', '&', request.url, flags=re.IGNORECASE)
            return redirect(url)

        form = request.args

    method   = form.get("method", "index")
    project  = form.get("project", "")
    filename = form.get("file", "")

    root = "/home/kirsle/www/projects"

    if project and filename:
        # Filter the sections.
        project = re.sub(r'[^A-Za-z0-9]', '', project) # Project name is alphanumeric only.
        filename = re.sub(r'[^A-Za-z0-9\-_\.]', '', filename)

        # Check that all the files exist.
        if os.path.isdir(os.path.join(root, project)) and os.path.isfile(os.path.join(root, project, filename)):
            # Hit counters.
            hits = { "hits": 0 }
            db = "data/downloads/{}-{}".format(project, filename)
            if JsonDB.exists(db.format(project, filename)):
                hits = JsonDB.get(db)

            # Actually getting the file?
            if method == "get":
                # Up the hit counter.
                hits["hits"] += 1
                JsonDB.commit(db, hits)

            g.info["method"] = method
            g.info["project"] = project
            g.info["file"] = filename
            g.info["hits"] = hits["hits"]
            return template("download.html")

    flash("The file or project wasn't found.")
    return redirect(url_for("index"))
コード例 #33
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")
コード例 #34
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def delete(key):
    """Delete a photo."""
    pic = Photo.get_photo(key)
    if not pic:
        flash("The photo wasn't found!")
        return redirect(url_for(".albums"))

    if request.method == "POST":
        # Do it.
        Photo.delete_photo(key)
        flash("The photo has been deleted.")
        return redirect(url_for(".albums"))

    g.info["key"] = key
    g.info["photo"] = pic

    return template("photos/delete.html")
コード例 #35
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def delete_album(album):
    """Delete an entire album."""
    photos = Photo.list_photos(album)
    if photos is None:
        flash("That album doesn't exist.")
        return redirect(url_for(".albums"))

    if request.method == "POST":
        # Do it.
        for photo in photos:
            Photo.delete_photo(photo["key"])
        flash("The album has been deleted.")
        return redirect(url_for(".albums"))

    g.info["album"] = album

    return template("photos/delete_album.html")
コード例 #36
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def album_index(name):
    """View the photos inside an album."""
    photos = Photo.list_photos(name)
    if photos is None:
        flash("That album doesn't exist.")
        return redirect(url_for(".albums"))

    g.info["album"]      = name
    g.info["album_info"] = Photo.get_album(name)
    g.info["markdown"]   = render_markdown(g.info["album_info"]["description"])
    g.info["photos"]     = photos

    # Render Markdown descriptions for photos.
    for photo in g.info["photos"]:
        photo["data"]["markdown"] = render_markdown(photo["data"].get("description", ""))

    return template("photos/album.html")
コード例 #37
0
def setup():
    """Initial setup to create the Admin user account."""

    # This can't be done if users already exist on the CMS!
    if User.exists(uid=1):
        flash(
            "This website has already been configured (users already created)."
        )
        return redirect(url_for("index"))

    if request.method == "POST":
        # Submitting the form.
        username = request.form.get("username", "")
        name = request.form.get("name", "")
        pw1 = request.form.get("password1", "")
        pw2 = request.form.get("password2", "")

        # Default name = username.
        if name == "":
            name = username

        # Lowercase the user.
        username = username.lower()
        if User.exists(username=username):
            flash("That username already exists.")
            return redirect(url_for(".setup"))

        # Validate the form.
        errors = validate_create_form(username, pw1, pw2)
        if errors:
            for error in errors:
                flash(error)
            return redirect(url_for(".setup"))

        # Create the account.
        uid = User.create(
            username=username,
            password=pw1,
            name=name,
            role="admin",
        )

        flash("Admin user created! Please log in now.".format(uid))
        return redirect(url_for(".login"))

    return template("account/setup.html")
コード例 #38
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def setup():
    """Initial setup to create the Admin user account."""

    # This can't be done if users already exist on the CMS!
    if User.exists(uid=1):
        flash("This website has already been configured (users already created).")
        return redirect(url_for("index"))

    if request.method == "POST":
        # Submitting the form.
        username = request.form.get("username", "")
        name     = request.form.get("name", "")
        pw1      = request.form.get("password1", "")
        pw2      = request.form.get("password2", "")

        # Default name = username.
        if name == "":
            name = username

        # Lowercase the user.
        username = username.lower()
        if User.exists(username=username):
            flash("That username already exists.")
            return redirect(url_for(".setup"))

        # Validate the form.
        errors = validate_create_form(username, pw1, pw2)
        if errors:
            for error in errors:
                flash(error)
            return redirect(url_for(".setup"))

        # Create the account.
        uid = User.create(
            username=username,
            password=pw1,
            name=name,
            role="admin",
        )

        flash("Admin user created! Please log in now.".format(uid))
        return redirect(url_for(".login"))


    return template("account/setup.html")
コード例 #39
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")
コード例 #40
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def referrers():
    g.info["referrers"] = Tracking.get_referrers()

    # Filter some of the links.
    for i, link in enumerate(g.info["referrers"]["referrers"]):
        # Clean up useless Google links.
        if "google" in link[0] and re.search(r'/(?:imgres|url|search|translate\w+)?/', link[0]):
            g.info["referrers"]["referrers"][i] = None

    # Make the links word-wrap properly.
    filtered = [
        [ re.sub(r'(.{20})', r'\1<wbr>', x[0]), x[1] ]
        for x in g.info["referrers"]["referrers"]
        if x is not None
    ]
    g.info["referrers"]["referrers"] = filtered

    return template("tracking/referrers.html")
コード例 #41
0
def legacy_download():
    form = None
    if request.method == "POST":
        form = request.form
    else:
        form = request.args

    method = form.get("method", "index")
    project = form.get("project", "")
    filename = form.get("file", "")

    root = "/home/kirsle/www/projects"

    if project and filename:
        # Filter the sections.
        project = re.sub(r'[^A-Za-z0-9]', '',
                         project)  # Project name is alphanumeric only.
        filename = re.sub(r'[^A-Za-z0-9\-_\.]', '', filename)

        # Check that all the files exist.
        if os.path.isdir(os.path.join(root, project)) and os.path.isfile(
                os.path.join(root, project, filename)):
            # Hit counters.
            hits = {"hits": 0}
            db = "data/downloads/{}-{}".format(project, filename)
            if JsonDB.exists(db.format(project, filename)):
                hits = JsonDB.get(db)

            # Actually getting the file?
            if method == "get":
                # Up the hit counter.
                hits["hits"] += 1
                JsonDB.commit(db, hits)

            g.info["method"] = method
            g.info["project"] = project
            g.info["file"] = filename
            g.info["hits"] = hits["hits"]
            return template("download.html")

    flash("The file or project wasn't found.")
    return redirect(url_for("index"))
コード例 #42
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def partial_tags():
    """Get a listing of tags and their quantities for the nav bar."""
    tags = Blog.get_categories()

    # Sort the tags by popularity.
    sort_tags = [ tag for tag in sorted(tags.keys(), key=lambda y: tags[y], reverse=True) ]
    result = []
    has_small = False
    for tag in sort_tags:
        result.append(dict(
            category=tag,
            count=tags[tag],
            small=tags[tag] < 3, # TODO: make this configurable
        ))
        if tags[tag] < 3:
            has_small = True

    g.info["tags"] = result
    g.info["has_small"] = has_small
    return template("blog/categories.inc.html")
コード例 #43
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def partial_tags():
    """Get a listing of tags and their quantities for the nav bar."""
    tags = Blog.get_categories()

    # Sort the tags by popularity.
    sort_tags = [ tag for tag in sorted(tags.keys(), key=lambda y: tags[y], reverse=True) ]
    result = []
    has_small = False
    for tag in sort_tags:
        result.append(dict(
            category=tag if len(tag) else Config.blog.default_category,
            count=tags[tag],
            small=tags[tag] < 10, # TODO: make this configurable
        ))
        if tags[tag] < 10:
            has_small = True

    g.info["tags"] = result
    g.info["has_small"] = has_small
    return template("blog/categories.inc.html")
コード例 #44
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")
コード例 #45
0
ファイル: kirsle_legacy.py プロジェクト: TeMbl4/rophako
def legacy_download():
    form = None
    if request.method == "POST":
        form = request.form
    else:
        form = request.args

    method   = form.get("method", "index")
    project  = form.get("project", "")
    filename = form.get("file", "")

    root = "/home/kirsle/www/projects"

    if project and filename:
        # Filter the sections.
        project = re.sub(r'[^A-Za-z0-9]', '', project) # Project name is alphanumeric only.
        filename = re.sub(r'[^A-Za-z0-9\-_\.]', '', filename)

        # Check that all the files exist.
        if os.path.isdir(os.path.join(root, project)) and os.path.isfile(os.path.join(root, project, filename)):
            # Hit counters.
            hits = { "hits": 0 }
            db = "data/downloads/{}-{}".format(project, filename)
            if JsonDB.exists(db.format(project, filename)):
                hits = JsonDB.get(db)

            # Actually getting the file?
            if method == "get":
                # Up the hit counter.
                hits["hits"] += 1
                JsonDB.commit(db, hits)

            g.info["method"] = method
            g.info["project"] = project
            g.info["file"] = filename
            g.info["hits"] = hits["hits"]
            return template("download.html")

    flash("The file or project wasn't found.")
    return redirect(url_for("index"))
コード例 #46
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")
コード例 #47
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")
コード例 #48
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def delete():
    """Delete a blog post."""
    post_id = request.args.get("id")

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

    if request.method == "POST":
        confirm = request.form.get("confirm")
        if confirm == "true":
            Blog.delete_entry(post_id)
            flash("The blog entry has been deleted.")
            return redirect(url_for(".index"))

    # Get the entry's subject.
    post = Blog.get_entry(post_id)
    g.info["subject"] = post["subject"]
    g.info["post_id"] = post_id

    return template("blog/delete.html")
コード例 #49
0
ファイル: __init__.py プロジェクト: kirsle/rophako
def delete():
    """Delete a blog post."""
    post_id = request.args.get("id")

    # Resolve the post ID.
    post_id = Blog.resolve_id(post_id, drafts=True)
    if not post_id:
        flash("That blog post wasn't found.")
        return redirect(url_for(".index"))

    if request.method == "POST":
        confirm = request.form.get("confirm")
        if confirm == "true":
            Blog.delete_entry(post_id)
            flash("The blog entry has been deleted.")
            return redirect(url_for(".index"))

    # Get the entry's subject.
    post = Blog.get_entry(post_id)
    g.info["subject"] = post["subject"]
    g.info["post_id"] = post_id

    return template("blog/delete.html")
コード例 #50
0
def index():
    return template("tracking/index.html")
コード例 #51
0
def legacy_firered(page=""):
    g.info["page"] = str(page) or "1"
    return template("firered.html")
コード例 #52
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def edit_user(uid):
    uid = int(uid)
    user = User.get_user(uid=uid)

    # Submitting?
    if request.method == "POST":
        action = request.form.get("action", "")
        username = request.form.get("username", "")
        name = request.form.get("name", "")
        pw1 = request.form.get("password1", "")
        pw2 = request.form.get("password2", "")
        role = request.form.get("role", "")

        username = username.lower()

        if action == "save":
            # Validate...
            errors = None

            # Don't allow them to change the username to one that exists.
            if username != user["username"]:
                if User.exists(username=username):
                    flash("That username already exists.")
                    return redirect(url_for(".edit_user", uid=uid))

            # Password provided?
            if len(pw1) > 0:
                errors = validate_create_form(username, pw1, pw2)
            elif username != user["username"]:
                # Just validate the username, then.
                errors = validate_create_form(username, skip_passwd=True)

            if errors:
                for error in errors:
                    flash(error)
                return redirect(url_for(".edit_user", uid=uid))

            # Update the user.
            user["username"] = username
            user["name"] = name or username
            user["role"] = role
            if len(pw1) > 0:
                user["password"] = User.hash_password(pw1)
            User.update_user(uid, user)

            flash("User account updated!")
            return redirect(url_for(".users"))

        elif action == "delete":
            # Don't let them delete themself!
            if uid == g.info["session"]["uid"]:
                flash("You shouldn't delete yourself!")
                return redirect(url_for(".edit_user", uid=uid))

            User.delete_user(uid)
            flash("User deleted!")
            return redirect(url_for(".users"))

    return template(
        "admin/edit_user.html",
        info=user,
    )
コード例 #53
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def update():
    """Post/edit a blog entry."""

    # Get our available avatars.
    g.info["avatars"] = Blog.list_avatars()
    g.info["userpic"] = User.get_picture(uid=g.info["session"]["uid"])

    # Default vars.
    g.info.update(dict(
        post_id="",
        fid="",
        author=g.info["session"]["uid"],
        subject="",
        body="",
        format="markdown",
        avatar="",
        categories="",
        privacy=Config.blog.default_privacy,
        emoticons=True,
        comments=Config.blog.allow_comments,
        month="",
        day="",
        year="",
        hour="",
        min="",
        sec="",
        preview=False,
    ))

    # Editing an existing post?
    post_id = request.args.get("id", None)
    if post_id:
        post_id = Blog.resolve_id(post_id)
        if post_id:
            logger.info("Editing existing blog post {}".format(post_id))
            post = Blog.get_entry(post_id)
            g.info["post_id"] = post_id
            g.info["post"] = post

            # Copy fields.
            for field in ["author", "fid", "subject", "format", "format",
                          "body", "avatar", "categories", "privacy",
                          "emoticons", "comments"]:
                g.info[field] = post[field]

            # Dissect the time.
            date = datetime.datetime.fromtimestamp(post["time"])
            g.info.update(dict(
                month="{:02d}".format(date.month),
                day="{:02d}".format(date.day),
                year=date.year,
                hour="{:02d}".format(date.hour),
                min="{:02d}".format(date.minute),
                sec="{:02d}".format(date.second),
            ))

    # Are we SUBMITTING the form?
    if request.method == "POST":
        action = request.form.get("action")

        # Get all the fields from the posted params.
        g.info["post_id"] = request.form.get("id")
        for field in ["fid", "subject", "format", "body", "avatar", "categories", "privacy"]:
            g.info[field] = request.form.get(field)
        for boolean in ["emoticons", "comments"]:
            g.info[boolean] = True if request.form.get(boolean, None) == "true" else False
        for number in ["author", "month", "day", "year", "hour", "min", "sec"]:
            g.info[number] = int(request.form.get(number, 0))

        # What action are they doing?
        if action == "preview":
            g.info["preview"] = True

            # Render markdown?
            if g.info["format"] == "markdown":
                g.info["rendered_body"] = render_markdown(g.info["body"])
            else:
                g.info["rendered_body"] = g.info["body"]

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

        elif action == "publish":
            # Publishing! Validate inputs first.
            invalid = False
            if len(g.info["body"]) == 0:
                invalid = True
                flash("You must enter a body for your blog post.")
            if len(g.info["subject"]) == 0:
                invalid = True
                flash("You must enter a subject for your blog post.")

            # Make sure the times are valid.
            date = None
            try:
                date = datetime.datetime(
                    g.info["year"],
                    g.info["month"],
                    g.info["day"],
                    g.info["hour"],
                    g.info["min"],
                    g.info["sec"],
                )
            except ValueError as e:
                invalid = True
                flash("Invalid date/time: " + str(e))

            # Format the categories.
            tags = []
            for tag in g.info["categories"].split(","):
                tags.append(tag.strip())

            # Okay to update?
            if invalid is False:
                # Convert the date into a Unix time stamp.
                epoch = float(date.strftime("%s"))

                new_id, new_fid = Blog.post_entry(
                    post_id    = g.info["post_id"],
                    epoch      = epoch,
                    author     = g.info["author"],
                    subject    = g.info["subject"],
                    fid        = g.info["fid"],
                    avatar     = g.info["avatar"],
                    categories = tags,
                    privacy    = g.info["privacy"],
                    ip         = remote_addr(),
                    emoticons  = g.info["emoticons"],
                    comments   = g.info["comments"],
                    format     = g.info["format"],
                    body       = g.info["body"],
                )

                return redirect(url_for(".entry", fid=new_fid))


    if type(g.info["categories"]) is list:
        g.info["categories"] = ", ".join(g.info["categories"])

    return template("blog/update.html")
コード例 #54
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def index():
    return template("admin/index.html")
コード例 #55
0
def visitors():
    g.info["history"] = Tracking.get_visitor_details()
    return template("tracking/visitors.html")
コード例 #56
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def category(category):
    g.info["url_category"] = category
    return template("blog/index.html")
コード例 #57
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def privacy():
    """The privacy policy and global unsubscribe page."""
    return template("comment/privacy.html")
コード例 #58
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)
コード例 #59
0
ファイル: __init__.py プロジェクト: TeMbl4/rophako
def index():
    return template("blog/index.html")