Refactor site articles
This commit is contained in:
parent
d991c17cac
commit
e577d67b16
|
@ -4,7 +4,7 @@ import os
|
|||
import shutil
|
||||
import tempfile
|
||||
|
||||
from .models import Article, Section, Site
|
||||
from jack.models import Article, Section, Site
|
||||
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
@ -17,24 +17,20 @@ def generate_site(input_path):
|
|||
|
||||
LOGGER.info("Processing static content to {}".format(root_directory))
|
||||
|
||||
site = Site(None)
|
||||
site = Site("Site name")
|
||||
|
||||
for root, dirs, files in os.walk(root_directory):
|
||||
base_name = root.replace(root_directory, "")
|
||||
|
||||
categories = [x for x in base_name.split(os.sep) if x]
|
||||
|
||||
if "_index.md" in files:
|
||||
section = Section(categories[-1])
|
||||
elif "index.md" in files:
|
||||
if "index.md" in files:
|
||||
with open(os.path.join(root, "index.md")) as md_file:
|
||||
content = md_file.read()
|
||||
|
||||
article = site.add(content)
|
||||
article.write(os.path.join(root, "index.html"))
|
||||
article = Article(content, base_name)
|
||||
article.write(root)
|
||||
else:
|
||||
LOGGER.warning(
|
||||
"{}: No `index.md` or `_index.md` files found in this directory. You might want to add one.".format(
|
||||
"{}: No `index.md` or `_index.md` files found in this directory.".format(
|
||||
root
|
||||
)
|
||||
)
|
||||
|
|
|
@ -11,14 +11,16 @@ LOGGER = logging.getLogger(__name__)
|
|||
|
||||
|
||||
def extract_metadata_from_content(content):
|
||||
BLOCK_RE = re.compile(r'^-{3}[ \t]*\n(.*?\n)(?:\.{3}|-{3})[ \t]*\n', re.UNICODE|re.DOTALL)
|
||||
BLOCK_RE = re.compile(
|
||||
r"^-{3}[ \t]*\n(.*?\n)(?:\.{3}|-{3})[ \t]*\n", re.UNICODE | re.DOTALL
|
||||
)
|
||||
|
||||
metadata = {}
|
||||
|
||||
if (match := BLOCK_RE.match(content)):
|
||||
if match := BLOCK_RE.match(content):
|
||||
try:
|
||||
metadata = yaml.safe_load(match.group(1))
|
||||
content = content[match.end():].lstrip('\n')
|
||||
content = content[match.end() :].lstrip("\n")
|
||||
except Exception as exc:
|
||||
LOGGER.warning("Unable to extract metadata: {}".format(exc))
|
||||
|
||||
|
@ -26,20 +28,24 @@ def extract_metadata_from_content(content):
|
|||
|
||||
|
||||
class Article:
|
||||
"""An article is composed by a content, associated to facultative tags and a category
|
||||
"""An article is composed by a content, associated to facultative tags and a category"""
|
||||
|
||||
"""
|
||||
def __init__(self, file_content: str, file_name: str, categories: list):
|
||||
self.meta, self.content = extract_metadata_from_content(file_content)
|
||||
def __init__(self, file_content: str, relative_file_path: str):
|
||||
self.meta, self.content = extract_metadata_from_content(file_content)
|
||||
self.title = self.meta.get("title")
|
||||
self.description = self.meta.get("description")
|
||||
self.tags = self.meta.get("tags", [])
|
||||
self.file_name = file_name
|
||||
self.relative_file_path = relative_file_path
|
||||
|
||||
if self.relative_file_path:
|
||||
self.sections = categories = [x for x in relative_file_path.split(os.sep) if x]
|
||||
else:
|
||||
self.sections = []
|
||||
|
||||
try:
|
||||
self.published_date = datetime.strptime(file_name[0:10], "%Y-%m-%d")
|
||||
except TypeError:
|
||||
self.published_date = datetime.strptime(self.sections[-1][0:10], "%Y-%m-%d")
|
||||
except (IndexError, TypeError, ValueError):
|
||||
self.published_date = None
|
||||
self.categories = categories
|
||||
|
||||
md = markdown.Markdown(extensions=["fenced_code"])
|
||||
self.html = md.convert(self.content)
|
||||
|
@ -47,8 +53,10 @@ class Article:
|
|||
def to_prose(self):
|
||||
return self.html
|
||||
|
||||
def write(self, output_path):
|
||||
with open(output_path, "w") as output_file:
|
||||
def write(self, root_output_path):
|
||||
with open(
|
||||
os.path.join(root_output_path, self.relative_file_path, "index.html"), "w"
|
||||
) as output_file:
|
||||
output_file.write(self.to_prose())
|
||||
|
||||
|
||||
|
@ -58,6 +66,7 @@ class Section:
|
|||
self.path = path
|
||||
self.parent = None
|
||||
self.sections = {}
|
||||
self.articles = []
|
||||
|
||||
def add(self, section):
|
||||
if section.key not in self.sections.keys():
|
||||
|
@ -67,24 +76,40 @@ class Section:
|
|||
return self.sections[section.key]
|
||||
|
||||
|
||||
class Tag:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.articles = []
|
||||
|
||||
def write(self, output_path):
|
||||
absolute_output_path = os.path.join(output_path, "tags", self.name)
|
||||
os.mkdir(absolute_output_path)
|
||||
|
||||
with open(os.path.join(absolute_output_path, "index.html"), "w") as html_file:
|
||||
html_file.write("""<html><body><p>Test</p></body></html>""")
|
||||
|
||||
def __eq__(self, o):
|
||||
if isinstance(o, type(Tag)) and o.name == self.name:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Site:
|
||||
"""A site contains articles, categories and all related data.
|
||||
"""
|
||||
"""A site contains articles, categories and all related data."""
|
||||
|
||||
def __init__(self, root_directory: str):
|
||||
self.root_directory = root_directory
|
||||
self.articles = []
|
||||
self.sections = {}
|
||||
self.tags = {}
|
||||
|
||||
def add(self, file_content: str):
|
||||
def add(self, article: Article):
|
||||
"""Add a new article to the current site
|
||||
|
||||
Returns:
|
||||
The newly created article
|
||||
"""
|
||||
|
||||
article = Article(file_content, None, None)
|
||||
|
||||
self.articles.append(article)
|
||||
|
||||
for tag in article.tags:
|
||||
|
@ -93,9 +118,21 @@ class Site:
|
|||
|
||||
return article
|
||||
|
||||
def add_section(self, section: Section):
|
||||
self.sections.setdefault(section.key, section)
|
||||
self.sections[section.key].articles.extend(section.articles)
|
||||
|
||||
def write(self):
|
||||
LOGGER.info("Writing site tags")
|
||||
...
|
||||
LOGGER.info("Writing site articles")
|
||||
for article in self.articles:
|
||||
article.write(self.root_directory)
|
||||
|
||||
LOGGER.info("Writing site categories")
|
||||
...
|
||||
print(len(self.articles))
|
||||
for section in self.sections:
|
||||
section.write(self.root_directory)
|
||||
|
||||
LOGGER.info("Writing site tags")
|
||||
for tag in self.tags:
|
||||
tag.write(self.root_directory)
|
||||
|
||||
print(len(self.articles))
|
||||
|
|
|
@ -9,6 +9,7 @@ tags:
|
|||
- python
|
||||
- dev
|
||||
- code
|
||||
writers: ["Ken Follet", "Gilles Legardinier"]
|
||||
---
|
||||
|
||||
This is the content
|
||||
|
@ -21,27 +22,31 @@ def this_is_a_python_function():
|
|||
"""
|
||||
|
||||
def test_article_metadata():
|
||||
article = Article(content, None, None)
|
||||
article = Article(content, None)
|
||||
assert article.title == "This is a test article"
|
||||
assert article.description == "Some fancy description"
|
||||
assert article.tags == ["python", "dev", "code"]
|
||||
|
||||
|
||||
def test_article_content():
|
||||
article = Article(content, None, None)
|
||||
article = Article(content, None)
|
||||
assert "title" not in article.content
|
||||
|
||||
|
||||
def test_article_published_date():
|
||||
article = Article(content, None, None)
|
||||
article = Article(content, None)
|
||||
assert article.published_date is None
|
||||
|
||||
|
||||
def test_article_fenced_code():
|
||||
article = Article(content, None, None)
|
||||
article = Article(content, None)
|
||||
assert """<pre><code class="language-python">""" in article.to_prose()
|
||||
|
||||
|
||||
def test_sections():
|
||||
article = Article(content, "a/b/c")
|
||||
|
||||
|
||||
def test_section_add():
|
||||
parent = Section("dev")
|
||||
child = Section("code")
|
||||
|
@ -64,7 +69,8 @@ def test_add_existing_section():
|
|||
|
||||
def test_site_append_article():
|
||||
site = Site(".")
|
||||
article = site.add(content)
|
||||
article = Article(content, None)
|
||||
site.add(article)
|
||||
|
||||
assert article in site.articles
|
||||
assert "python" in site.tags
|
||||
|
|
Loading…
Reference in New Issue