Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1fa2466f14ce5e47a7542f8eae4b2af754038f8f
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,26 @@ jobs:
-Dsonar.python.coverage.reportPaths=coverage.xml \
-Dsonar.projectName=Blask \
-Dsonar.host.url=https://sonarcloud.io

black:
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@v2

- name: Setup python 3.7
uses: actions/setup-python@v2
with:
python-version: "3.7"
architecture: "x64"

- name: Install Black
run: pip install black

- name: Auto-format with Black and commit format changes only if there are changes
run: |
black .
git config user.name 'autoblack'
git config user.email '<autoblack@github.com>'
git diff --quiet HEAD || git commit -am "fixup: Format Python code with Black"
git push
4 changes: 4 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ pytest-cov = ">=2.7.1"
pytest-mock = ">=1.10.4"
coveralls = ">=1.3.0"
pylint = "*"
black = "*"

[scripts]
test = "pytest --cov=blask --cov-report=xml"
linter = "pylint blask --exit-zero"

[pipenv]
allow_prereleases = true
452 changes: 220 additions & 232 deletions Pipfile.lock

Large diffs are not rendered by default.

4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# BLASK

[![Build Status](https://travis-ci.org/zerasul/blask.svg?branch=master)](https://travis-ci.org/zerasul/blask) [![Coverage Status](https://coveralls.io/repos/github/zerasul/blask/badge.svg?branch=master)](https://coveralls.io/github/zerasul/blask?branch=master) [![sonarcloud-quality-gate](https://sonarcloud.io/api/project_badges/measure?project=blask-project-key&metric=alert_status)](https://sonarcloud.io/dashboard?id=blask-project-key)[![PyPI version](https://badge.fury.io/py/Blask.svg)](https://badge.fury.io/py/Blask) [![Downloads](http://pepy.tech/badge/blask)](http://pepy.tech/count/blask) [![Docker Image Version (tag latest semver)](https://img.shields.io/docker/v/zerasul/blask/0.2.3?color=green&logo=docker)](https://hub.docker.com/r/zerasul/blask) <span class="badge-buymeacoffee"><a href="https://buymeacoffee.com/zerasul" title="Donate to this project using Buy Me A Coffee"><img src="https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg" alt="Buy Me A Coffee donate button" /></a></span>

[![Coverage Status](https://coveralls.io/repos/github/zerasul/blask/badge.svg?branch=main)](https://coveralls.io/github/zerasul/blask?branch=main)
[![Build Status](https://travis-ci.org/zerasul/blask.svg?branch=master)](https://travis-ci.org/zerasul/blask) [![Coverage Status](https://coveralls.io/repos/github/zerasul/blask/badge.svg?branch=main)](https://coveralls.io/github/zerasul/blask?branch=main) [![sonarcloud-quality-gate](https://sonarcloud.io/api/project_badges/measure?project=blask-project-key&metric=alert_status)](https://sonarcloud.io/dashboard?id=blask-project-key) [![PyPI version](https://badge.fury.io/py/Blask.svg)](https://badge.fury.io/py/Blask) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![Downloads](http://pepy.tech/badge/blask)](http://pepy.tech/count/blask) [![Docker Image Version (tag latest semver)](https://img.shields.io/docker/v/zerasul/blask/0.2.3?color=green&logo=docker)](https://hub.docker.com/r/zerasul/blask) <span class="badge-buymeacoffee"><a href="https://buymeacoffee.com/zerasul" title="Donate to this project using Buy Me A Coffee"><img src="https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg" alt="Buy Me A Coffee donate button" /></a></span>

Blask is a blogging engine based on [Flask](http://flask.pocoo.org/). Blask uses Markdown syntax to create and render the contents of blog posts.

Expand Down
42 changes: 22 additions & 20 deletions blask/blaskapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,28 +47,28 @@ def __init__(self, **kwargs):
template_folder=self.settings["templateDir"],
static_folder=self.settings["staticDir"],
)

self.csrf = CSRFProtect()
self.csrf.init_app(self.app)

self.app.add_url_rule(
"/", endpoint="index", view_func=self._index, methods=["GET"])
self.app.add_url_rule(
"/sitemap.xml", view_func=self._get_sitemap, methods=["GET"])
self.app.add_url_rule(
"/<filename>", view_func=self._getpage, methods=["GET"])
self.app.add_url_rule(
"/<path:subpath>/<filename>",
view_func=self._get_subpage, methods=["GET"])
"/", endpoint="index", view_func=self._index, methods=["GET"]
)
self.app.add_url_rule(
"/tag/<tag>", view_func=self._gettag, methods=["GET"])
"/sitemap.xml", view_func=self._get_sitemap, methods=["GET"]
)
self.app.add_url_rule("/<filename>", view_func=self._getpage, methods=["GET"])
self.app.add_url_rule(
"/search", view_func=self.searchpages, methods=["POST"])
"/<path:subpath>/<filename>", view_func=self._get_subpage, methods=["GET"]
)
self.app.add_url_rule("/tag/<tag>", view_func=self._gettag, methods=["GET"])
self.app.add_url_rule("/search", view_func=self.searchpages, methods=["POST"])
self.app.add_url_rule(
"/category/<category>",
view_func=self._getcategory, methods=["GET"])
"/category/<category>", view_func=self._getcategory, methods=["GET"]
)
self.app.add_url_rule(
"/author/<author>", view_func=self._getauthor, methods=["GET"])
"/author/<author>", view_func=self._getauthor, methods=["GET"]
)
# Register the error handler for each setting
for error in self.settings["errors"].keys():
self.app.register_error_handler(error, f=self._handle_http_errors)
Expand All @@ -83,7 +83,8 @@ def _index(self):
if template is None:
template = self.settings["defaultLayout"]
return render_template(
template, title=self.settings["title"], content=entry.content)
template, title=self.settings["title"], content=entry.content
)

def _getpage(self, filename):
"""
Expand Down Expand Up @@ -129,7 +130,8 @@ def _get_sitemap(self):
"""
return Response(
self.blogrenderer.generate_sitemap_xml(
self.settings["postDir"], request.url_root),
self.settings["postDir"], request.url_root
),
content_type="text/xml",
)

Expand All @@ -144,7 +146,7 @@ def _gettag(self, tag):
return render_template(
self.settings["defaultLayout"],
title=self.settings["title"],
content=content
content=content,
)

def searchpages(self):
Expand All @@ -157,7 +159,7 @@ def searchpages(self):
return render_template(
self.settings["defaultLayout"],
title=self.settings["title"],
content=content
content=content,
)

def _getcategory(self, category):
Expand All @@ -171,7 +173,7 @@ def _getcategory(self, category):
return render_template(
self.settings["defaultLayout"],
title=self.settings["title"],
content=content
content=content,
)

def _getauthor(self, author):
Expand All @@ -185,7 +187,7 @@ def _getauthor(self, author):
return render_template(
self.settings["defaultLayout"],
title=self.settings["title"],
content=content
content=content,
)

def _handle_http_errors(self, error_message):
Expand Down
33 changes: 20 additions & 13 deletions blask/blaskcli.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ class CLIController:
Class that controls all the Command Line interface application
"""

default_template_file = str(LIB_DIR / 'index_template.html')
default_template_file = str(LIB_DIR / "index_template.html")

default_index = str(LIB_DIR / 'markdown_template.md')
default_index = str(LIB_DIR / "markdown_template.md")

settings = str(LIB_DIR / 'default_env.env')
settings = str(LIB_DIR / "default_env.env")

not_found = str(LIB_DIR / 'default_404.md')
not_found = str(LIB_DIR / "default_404.md")

docker_template = str(LIB_DIR / 'Dockerfile_template')
docker_template = str(LIB_DIR / "Dockerfile_template")

def createdefaultindexfile(self, filepath):
"""
Expand All @@ -61,7 +61,7 @@ def createsettingsfile(self):
"""
Create a new settings file
"""
shutil.copy(self.settings, '.env')
shutil.copy(self.settings, ".env")

def createnotfoundpage(self, filepath):
"""
Expand Down Expand Up @@ -97,9 +97,13 @@ def main() -> None:

@blaskcli.command(help="Run the instance of blask")
def run(
debug: bool = typer.Option(False, "--debug", help="Init with de debug flag", is_flag=True),
debug: bool = typer.Option(
False, "--debug", help="Init with de debug flag", is_flag=True
),
port: int = typer.Option(5000, "--port", help="Port where the server is listening"),
host: str = typer.Option("127.0.0.1", "--host", help="Default Network interface listening"),
host: str = typer.Option(
"127.0.0.1", "--host", help="Default Network interface listening"
),
) -> None:
"""
Run the current blask instance
Expand All @@ -112,7 +116,10 @@ def run(
@blaskcli.command(help="Initialize a new blask Project")
def init(
with_docker: bool = typer.Option(
False, "--with-docker", help="Add a DockerFile to the blask directory", is_flag=True
False,
"--with-docker",
help="Add a DockerFile to the blask directory",
is_flag=True,
)
) -> None:
"""
Expand All @@ -122,18 +129,18 @@ def init(
typer.echo("Initializing new blask Project")
typer.echo("Using default Settings")
postdir = path.basename(
path.dirname(str(blasksettings.DEFAULT_SETTINGS["postDir"] + "/")))
path.dirname(str(blasksettings.DEFAULT_SETTINGS["postDir"] + "/"))
)
templatedir = path.basename(
path.dirname(str(blasksettings.DEFAULT_SETTINGS["templateDir"] + "/"))
)
try:
makedirs(postdir)
cliController.createdefaultindexfile(path.join(postdir, "index.md"))
makedirs(templatedir)
cliController.createdefaulttemplatefile(
path.join(templatedir, "template.html"))
cliController.createdefaulttemplatefile(path.join(templatedir, "template.html"))
cliController.createsettingsfile()
cliController.createnotfoundpage(path.join(postdir, '404.md'))
cliController.createnotfoundpage(path.join(postdir, "404.md"))
if with_docker:
cliController.createdockerfile(path.join("Dockerfile"))
typer.echo("Created new blask project on %s" % getcwd())
Expand Down
7 changes: 4 additions & 3 deletions blask/blasksettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
"defaultLayout": str("template.html"),
"staticDir": str(BASE_DIR / "static"),
"title": "blask | A Simple Blog Engine Based on Flask",
"errors": {404: "404"} # Dictionary with errors handler
"errors": {404: "404"}, # Dictionary with errors handler
}


class BlaskSettings(): # pylint: disable=too-few-public-methods
class BlaskSettings: # pylint: disable=too-few-public-methods
"""
blask configuration helper class
"""
Expand All @@ -54,7 +54,8 @@ def __init__(self, **kwargs):
path.append(os.getcwd())
# Load settings from the module in environment variable
settings_mod = import_module(
os.environ["BLASK_SETTINGS"], os.environ["BLASK_SETTINGS"])
os.environ["BLASK_SETTINGS"], os.environ["BLASK_SETTINGS"]
)

self.settings = {}
for key in DEFAULT_SETTINGS:
Expand Down
38 changes: 19 additions & 19 deletions blask/blogrenderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
INDEX = "index.md"
DATE_FORMAT = "%Y-%m-%d"


class BlogRenderer:
"""
Class BlogRenderer: This class provides the feature for render posts from
Expand Down Expand Up @@ -66,7 +67,8 @@ def renderfile(self, filename):
would fall out of the posts directory.
"""
page_not_exist_exception = PageNotExistError(
f"{filename} does not exists in {self.postdir} directory")
f"{filename} does not exists in {self.postdir} directory"
)
try:
file = f"{filename}.md"
filepath = safe_join(self.postdir, file)
Expand All @@ -93,20 +95,19 @@ def rendertext(self, filename, text):
:param text: Text write in Markdown.
:return: BlogEntry.
"""
mark_down = Markdown(
extensions=["meta", "markdown.extensions.codehilite"])
mark_down = Markdown(extensions=["meta", "markdown.extensions.codehilite"])
entry = BlogEntry(filename, mark_down, text)
return entry

# pylint: disable=dangerous-default-value
def list_posts(
self,
tags=None,
exclusions=[INDEX, "404.md"],
search="",
category="",
author="",
orderbydate=True,
self,
tags=None,
exclusions=[INDEX, "404.md"],
search="",
category="",
author="",
orderbydate=True,
):
"""
Search a list of Posts returning a list of BlogEntry ordered By Date.
Expand Down Expand Up @@ -139,10 +140,8 @@ def list_posts(
if orderbydate:
# create a sublist with only entries with date
dateredentries = list(filter(lambda e: e.date is None, entries))
notdateredentries = list(
filter(lambda d: d.date is not None, entries))
entries = list(
sorted(dateredentries, key=lambda t: t.date, reverse=True))
notdateredentries = list(filter(lambda d: d.date is not None, entries))
entries = list(sorted(dateredentries, key=lambda t: t.date, reverse=True))
entries.extend(notdateredentries)
return entries

Expand All @@ -156,8 +155,9 @@ def _listdirectoriesrecursive(self, directory, append=""):
for file in listdir(directory):
if path.isdir(safe_join(directory, file)):
posts.extend(
self._listdirectoriesrecursive(safe_join(directory, file),
safe_join(append, file))
self._listdirectoriesrecursive(
safe_join(directory, file), safe_join(append, file)
)
)
else:
posts.append(safe_join(append, file))
Expand All @@ -170,8 +170,8 @@ def generate_sitemap_xml(self, postlist, baseurl="http://localhost:5000"):
:return: return the xml output for the Sitemap.xml file.
"""
root = ET.Element(
"urlset",
attrib={"xmlns": "http://www.sitemaps.org/schemas/sitemap/0.9"})
"urlset", attrib={"xmlns": "http://www.sitemaps.org/schemas/sitemap/0.9"}
)
rpostlist = self._listdirectoriesrecursive(postlist)
rpostlist.remove(INDEX)
rpostlist = list(map(lambda l: path.splitext(l)[0], rpostlist))
Expand Down Expand Up @@ -224,7 +224,7 @@ def generatetagpage(self, postlist):

# pylint: disable=too-few-public-methods
class BlogEntry:
""""
""" "
This class has the information about the Blog Posts.
Author: Zerasul
Version: 0.0.1.
Expand Down
9 changes: 4 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import argparse
import logging
from blask import BlaskApp

application = BlaskApp().app

if __name__ == '__main__':
if __name__ == "__main__":
# Argument parsing
parser = argparse.ArgumentParser()
parser.add_argument(
"-d", "--debug", action='store_true', help="Verbose output")
parser.add_argument(
"-v", "--verbose", action='store_true', help="Verbose output")
parser.add_argument("-d", "--debug", action="store_true", help="Verbose output")
parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output")
args = parser.parse_args()
if args.debug or args.verbose:
log = logging.getLogger()
Expand Down
2 changes: 1 addition & 1 deletion settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pathlib import Path

BASE_DIR = Path('.').resolve()
BASE_DIR = Path(".").resolve()

templateDir = str(BASE_DIR / "templates")
postDir = "posts"
Expand Down
Loading