Premier commit
This commit is contained in:
0
blog/__init__.py
Normal file
0
blog/__init__.py
Normal file
59
blog/blog.py
Normal file
59
blog/blog.py
Normal file
@@ -0,0 +1,59 @@
|
||||
import glob
|
||||
from pathlib import Path
|
||||
from blog.page import Page
|
||||
from blog.config import Config
|
||||
from jinja2 import Environment, FileSystemLoader, Template
|
||||
|
||||
|
||||
class Blog:
|
||||
|
||||
def __init__(self, conf: Config):
|
||||
""" """
|
||||
self.conf = conf
|
||||
self.pages = dict()
|
||||
|
||||
def load_pages(self):
|
||||
"""Charge tous les fichiers .md dans le dossier inbox"""
|
||||
files_list = glob.glob(f"{self.conf.inbox}/*.md")
|
||||
|
||||
self.pages = dict()
|
||||
for file in files_list:
|
||||
self.pages[Path(file).stem] = Page(Path(file))
|
||||
|
||||
def make(self):
|
||||
"""Convertit les pages en un site html"""
|
||||
if not self.pages:
|
||||
self.load_pages()
|
||||
|
||||
env = Environment(loader=FileSystemLoader(self.conf.theme))
|
||||
|
||||
page_template = env.get_template("page.html.j2")
|
||||
index_template = env.get_template("index.html.j2")
|
||||
|
||||
self._build_all_pages(page_template)
|
||||
self._build_index(index_template)
|
||||
|
||||
def _build_all_pages(self, template: Template):
|
||||
"""Convertit les pages markdown dans conf.inbox en html dans conf.outbox"""
|
||||
|
||||
outbox_path = Path(f"{self.conf.outbox}/pages")
|
||||
if not outbox_path.is_dir():
|
||||
outbox_path.mkdir()
|
||||
|
||||
for filename in self.pages:
|
||||
html_content = self.pages[filename].html(template)
|
||||
with open(f"{self.conf.outbox}/pages/{filename}.html", "w+") as html_file:
|
||||
html_file.write(html_content)
|
||||
|
||||
def _build_index(self, template: Template):
|
||||
"""Crée l'index du blog."""
|
||||
html_content = template.render(
|
||||
pages=self.pages, title=self.conf.title, presentation=self.conf.presentation
|
||||
)
|
||||
with open(f"{self.conf.outbox}/index.html", "w+") as html_file:
|
||||
html_file.write(html_content)
|
||||
|
||||
# def _copycss_files(src_dir: str, dest_dir: str) -> list:
|
||||
# list_css = glob.glob(f'{src_dir}/css/*.css')
|
||||
# for css_file in list_css:
|
||||
# shutil.copy(css_file, dest_dir)
|
29
blog/config.py
Normal file
29
blog/config.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import yaml
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
class Config:
|
||||
|
||||
_conf = dict()
|
||||
_list_valid_parameters = {"inbox", "outbox", "theme", "title", "presentation"}
|
||||
|
||||
def __init__(self, config_file: Path):
|
||||
"""Constructeur : charge les paramètres depuis le fichier de configuration"""
|
||||
with open(config_file) as cfile:
|
||||
self._conf = yaml.safe_load(cfile.read())
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""Renvoie la valeur d'un paramètre"""
|
||||
if name not in self._list_valid_parameters:
|
||||
raise AttributeError(f"L'attribut '{name}' n'existe pas.")
|
||||
|
||||
if name in self._conf:
|
||||
return self._conf[name]
|
||||
|
||||
return "undefined"
|
||||
|
||||
def overload(self, parameters: dict):
|
||||
"""Surcharge les paramètres depuis une liste fournie"""
|
||||
for valid_parameter in self._list_valid_parameters:
|
||||
if valid_parameter in parameters:
|
||||
self._conf[valid_parameter] = parameters[valid_parameter]
|
104
blog/page.py
Normal file
104
blog/page.py
Normal file
@@ -0,0 +1,104 @@
|
||||
import re
|
||||
import os
|
||||
import yaml
|
||||
import jinja2
|
||||
import textwrap
|
||||
import markdown
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from datetime import date, datetime
|
||||
|
||||
# from bs4 import BeautifulSoup as bs
|
||||
|
||||
|
||||
def new_page(title: str):
|
||||
"""Crée un nouvel article à partir du titre de celui ci."""
|
||||
|
||||
today = date.today().strftime("%Y-%m-%d")
|
||||
|
||||
filename = "./inbox/" + re.sub("[^a-zA-Z0-9-]", "_", title) + ".md"
|
||||
|
||||
content = textwrap.dedent(
|
||||
f"""\
|
||||
---
|
||||
date: {today}
|
||||
title: {title}
|
||||
category:
|
||||
tags:
|
||||
-
|
||||
---
|
||||
# {title}
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
if not os.path.exists(filename):
|
||||
with open(filename, "w") as file:
|
||||
file.write(content)
|
||||
|
||||
subprocess.run(["nvim", "+normal G$", "+startinsert", filename])
|
||||
|
||||
|
||||
class Page:
|
||||
|
||||
meta = dict()
|
||||
md_content = ""
|
||||
filename = ""
|
||||
|
||||
def __init__(self, filename: Path):
|
||||
"""Constructeur : nouvelle page"""
|
||||
self.filename = filename
|
||||
|
||||
with open(filename) as file:
|
||||
meta, self.md_content = self._extract_meta_and_markdown(file.read())
|
||||
self.meta = yaml.safe_load(meta)
|
||||
|
||||
if "title" not in self.meta:
|
||||
self.meta["title"] = Path(filename).stem
|
||||
|
||||
if "date" not in self.meta or type(self.meta["date"]) is not date:
|
||||
self.meta["date"] = date(1970, 1, 1)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name not in self.meta:
|
||||
raise AttributeError(f"L'attribut '{name}' n'existe pas.")
|
||||
|
||||
# if name == date:
|
||||
# return datetime(self.meta['date'], "%Y-%m-%d")
|
||||
|
||||
return self.meta[name]
|
||||
|
||||
def _extract_meta_and_markdown(self, content: str) -> list:
|
||||
""" """
|
||||
is_meta = False
|
||||
is_markdown = False
|
||||
meta = ""
|
||||
markdown = ""
|
||||
for line in content.splitlines():
|
||||
if line == "---":
|
||||
if not is_meta:
|
||||
is_meta = True
|
||||
else:
|
||||
is_markdown = True
|
||||
else:
|
||||
if is_markdown:
|
||||
markdown += line + "\n"
|
||||
elif is_meta:
|
||||
meta += line + "\n"
|
||||
return meta, markdown
|
||||
|
||||
def html(self, template: jinja2.Template) -> str:
|
||||
"""Convertit la page en html a partir d'un template jinja2"""
|
||||
title = self.meta["title"] or "Sans titre"
|
||||
date = self.meta["date"] or None
|
||||
return template.render(
|
||||
title=title,
|
||||
date=date,
|
||||
content=markdown.markdown(
|
||||
self.md_content, extensions=["codehilite", "fenced_code"]
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
# from bs4 import BeautifulSoup as bs
|
||||
# print(bs(html_string, 'html.parser').prettify())
|
17
blog/theme.py
Normal file
17
blog/theme.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import glob
|
||||
from pathlib import Path
|
||||
from blog.page import Page
|
||||
from blog.config import Config
|
||||
from jinja2 import Environment, FileSystemLoader, Template
|
||||
|
||||
|
||||
class Theme:
|
||||
|
||||
def __init__(self, path: Path):
|
||||
""" """
|
||||
self.path = path
|
||||
|
||||
|
||||
def _list_css(self)
|
||||
""" """
|
||||
pass
|
6
blog/utils.py
Normal file
6
blog/utils.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def clean_output(path: Path):
|
||||
# TODO
|
||||
pass
|
Reference in New Issue
Block a user