示例#1
0
def delete_comment() -> None:
    comment_id = int(input("Comment ID: "))
    if comment := db.query(Comment).get(comment_id):
        db.delete(comment)
        print(f"Deleted comment \"{comment.name}\".")
        save_tip()
        return
示例#2
0
 def concrete():
     name = input(input_question)
     if obj := db.query(row_class).filter_by(name=name).first():
         print(f"{deleted_prefix} \"{obj.name}\".")
         db.delete(obj)
         save_tip()
         return
示例#3
0
def get_blog_post_by_id() -> BlogPost:
    try:
        blog_post_id = int(input("Blog Post ID: "))
    except ValueError:
        print("Invalid ID!")
        raise PostNotFoundException()

    if (blog_post := db.query(BlogPost).get(blog_post_id)) is None:
        print(f"No post with ID {blog_post_id}!")
        raise PostNotFoundException()
示例#4
0
def delete_author() -> None:
    author_name = input("Author Name: ")
    if author := db.query(Author).filter_by(name=author_name).first():
        for blog_post in author.blog_posts:
            print(f"Deleted blog post \"{blog_post.name}\".")
            shutil.rmtree(blog_post.slug_path)
            db.delete(blog_post)

        db.delete(author)
        print(f"Deleted author \"{author.name}\".")
        save_tip()
        return
示例#5
0
def show_posts() -> None:
    if posts := db.query(BlogPost).all():
        longest_title = max(len(post.name) for post in posts)
        longest_author = max(len(post.author.name) for post in posts)
        print(f"|  ID | {'Title'.rjust(longest_title)} | {'Author'.rjust(longest_author)} | "
              f"Hits | Commentable | In Graph | Hidden |")

        print(f"|-----|-{'-' * longest_title}-|-{'-' * longest_author}-|------|-------------|----------|--------|")
        for post in posts:
            print(f"| {str(post.id).rjust(3)} | {post.name.rjust(longest_title)} | "
                  f"{post.author.name.rjust(longest_author)} | "
                  f"{str(post.hits).rjust(4)} | "
                  f"     {x_if_true(post.allow_comments)}      | "
                  f"    {x_if_true(post.include_in_graph)}    | "
                  f"   {x_if_true(post.hidden)}   |")
示例#6
0
def generate_sitemap() -> str:
    # Semi-minimal sitemap implementation according to https://www.sitemaps.org/protocol.html
    urlset = eT.Element("urlset", xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
    insert_url = functools.partial(_insert_url, urlset, get_base_url())
    insert_url(loc="", priority=1)

    for post in db.query(BlogPost):
        insert_url(loc=url_for("home.route_blog_post", blog_post_id=post.id, _name=post.slug),
                   priority=0.8)

    for tag in db.query(Tag):
        insert_url(loc=url_for("home.route_tag", tag_id=tag.id, _name=tag.slug),
                   priority=0.6)

    for author in db.query(Author):
        insert_url(loc=url_for("home.route_author", author_id=author.id, _name=author.slug),
                   priority=0.4)

    return XML_HEADER + eT.tostring(urlset, encoding="unicode", method="xml")
示例#7
0
def route_root() -> any:
    quote = random.choice(route_root.quotes)

    friends = db.query(Friend).all()
    category_tags = [
        tag for tag in db.query(Tag).filter_by(main_section=True)
        if tag.blog_posts
    ]
    blog_posts = get_all_visible_blog_posts().order_by(
        BlogPost.timestamp.desc()).limit(5).all()

    return render_template("home.html",
                           title="Root",
                           header="Welcome to the Flesh-Network.",
                           sub_header=quote,
                           blog_posts=blog_posts,
                           friends=friends,
                           category_tags=category_tags,
                           quote=quote)
示例#8
0
def spellcheck() -> None:
    en_checker = SpellChecker(language="en")
    de_checker = SpellChecker(language="de")
    for post in db.query(BlogPost):
        markdown = read_file(post.markdown_path)
        for i, line in enumerate(markdown.splitlines()):
            words = [re.sub(r"[^a-zA-Z ]", "", word) for word in line.replace("-", " ").split()]
            words = [word for word in words if word]

            unknown_en_words = en_checker.unknown(words)
            unknown_de_words = de_checker.unknown(words)

            unknown_words = [word for word in unknown_en_words if word in unknown_de_words]

            for unknown_word in unknown_words:
                print(f"In \"{post.name}\" (line {i + 1}): Unknown word \"{unknown_word}\".")

    done()
示例#9
0
def detach_tag() -> None:
    tag_name = input("Tag Name: ")
    if not (tag := db.query(Tag).filter_by(name=tag_name).first()):
        print("Tag not found!")
        return
示例#10
0
def get_all_nodes() -> any:
    return db.query(BlogPost).filter_by(include_in_graph=True)
示例#11
0
def create_blog_post() -> None:
    author_name = input("Author Name: ")
    if not (author := db.query(Author).filter_by(name=author_name).first()):
        print(f"No author with name: \"{author_name}\".")
        exit()
示例#12
0
def get_all_blog_posts() -> any:
    return db.query(BlogPost).filter_by(include_in_graph=False)
示例#13
0
 def handle_404_error(exception: HTTPException) -> any:
     random_blog_posts = random.sample(db.query(BlogPost).all(), 5)
     return render_template("error_404.html", title=format_exception(exception), blog_posts=random_blog_posts,
                            exception=exception, return_to_root=True), exception.code
示例#14
0
def route_blog_post(blog_post_id: int, _name: str = "") -> any:
    if (blog_post := db.query(BlogPost).get(blog_post_id)) is None:
        abort(404)
示例#15
0
def show_rows(row_class: type) -> None:
    if rows := db.query(row_class).all():
        print(f"Currently registered {row_class.__name__}s:")
        for row in rows:
            print(f" * {str(row.id).rjust(3)} - \"{row.name}\"")
示例#16
0
def select_object(row_class: type) -> None:
    object_id = int(input(f"{row_class.__name__} ID: "))
    if not (result := db.query(row_class).get(object_id)):
        print(f"No object of type {row_class.__name__} with ID {object_id} exists.")
        return
示例#17
0
    print(f"Attached tag \"{tag.name}\" to post \"{blog_post.name}\"!")
    tag_association = TagAssociation(blog_post.id, tag.id)
    db.add(tag_association)
    save_tip()


def detach_tag() -> None:
    tag_name = input("Tag Name: ")
    if not (tag := db.query(Tag).filter_by(name=tag_name).first()):
        print("Tag not found!")
        return

    blog_post = get_blog_post_by_id()

    if (tag_association := db.query(TagAssociation).filter_by(blog_post_id=blog_post.id, tag_id=tag.id)
            .first()) is None:
        print("Tag is not attached to post!")
        return

    print(f"Detached tag \"{tag.name}\" from post \"{blog_post.name}\"!")
    db.delete(tag_association)
    save_tip()


def exit_program() -> None:
    print("Exiting...\n")
    sys.exit(0)


def save_changes() -> None:
    print("Saving changes... ", end="")
示例#18
0
def get_all_visible_blog_posts() -> any:
    return db.query(BlogPost).filter_by(hidden=False)
示例#19
0
def route_backlinks() -> Response:
    return render_template("backlinks.html",
                           title="Backlinks",
                           return_to_root=True,
                           hostnames=db.query(ReferrerHostname).all())
示例#20
0
def route_tag(tag_id: int, _name: str = "") -> any:
    # The "name" parameter is called "_name" to avoid unused variable
    # warnings in PyCharm. It is not beautiful but better than someone
    # removing them just by following suggestions.
    if (tag := db.query(Tag).get(tag_id)) is None:
        abort(404)
示例#21
0
def route_author(author_id: int, _name: str = "") -> any:
    if (author := db.query(Author).get(author_id)) is None:
        abort(404)
示例#22
0
        # A file reference
        if decoded_reference := has_prefix(reference, "file:"):
            name_mapping = {
                fr.clear_name: fr.name
                for fr in blog_post.file_resources
            }
            if hashed_file_name := name_mapping.get(decoded_reference):
                return "/" + in_res_path(hashed_file_name)

            # If the filename isn't in the mapping, the file doesn't exist.
            critical_error(f"Missing resource \"{decoded_reference}\"!")

        # An author reference
        if decoded_reference := has_prefix(reference, "author:"):
            if author := db.query(Author).filter_by(
                    name=decoded_reference).first():
                return f"/authors/{author.id}/{author.slug}/"

            critical_error(f"Missing author \"{decoded_reference}\"!")

        # A post reference
        if decoded_reference := has_prefix(reference, "post:"):
            if post := db.query(BlogPost).get(int(decoded_reference)):
                return f"/posts/{post.id}/{post.slug}/"

            critical_error(f"Missing post \"{decoded_reference}\"!")

        # A tag reference
        if decoded_reference := has_prefix(reference, "tag:"):
            if tag := db.query(Tag).filter_by(name=decoded_reference).first():
                return f"/tags/{tag.id}/{tag.slug}/"
示例#23
0
def get_all_posts() -> any:
    return db.query(BlogPost)