Compare commits

...

2 Commits

5 changed files with 125 additions and 46 deletions

View File

@ -6,6 +6,10 @@ import re
import os
import logging
from slugify import slugify
from .schema import CategorySchema
logger = logging.getLogger(__name__)
@ -55,12 +59,38 @@ def split(file_path):
return os.path.normpath(file_path).split(os.sep)
class Article(object):
class NamedSlug():
"""NamedSlug are mixins with a name and an auto-generated slug."""
def __init__(self, name):
self.name = name
self.slug = slugify(self.name)
def __init__(self, path, content, publication_date=None):
class Category(NamedSlug):
"""Categories are named, have slug and an empty list of articles."""
def __init__(self, name):
super().__init__(name)
self.articles = []
def append(self, article):
self.articles.append(article.slug)
class Content():
def __init__(self, path, content):
self.path = path
self.content = content
class Page(Content):
pass
class Article(Content):
def __init__(self, path, content, category, keywords=[], publication_date=None):
super().__init__(path, content)
split_path = split(path)
self.filename = split_path[-1] # the last element
@ -77,12 +107,8 @@ class Article(object):
if self.slug and self.slug.startswith('-'):
self.slug = self.slug[1:]
try:
self.category = split_path[1] #
self.keywords = split_path[2:-1]
except IndexError:
self.category = ''
self.keywords = []
self.category_name = category
self.keywords = keywords
try:
self.title = content.splitlines()[0]
@ -121,13 +147,15 @@ class Site(object):
Args:
root_path (path): The path where articles are stored.
articles (array): contain all articles.
"""
def __init__(self, root_path='articles'):
def __init__(self, root_path, output_path):
self.articles = []
self.pages = []
self.categories = {}
self.keywords = {}
self.root_path = root_path
self.output_path = output_path
for root, *_, files in os.walk(root_path):
for file in [file for file in files if file.endswith(".md")]:
@ -152,27 +180,40 @@ class Site(object):
article_file_path = os.path.join(filepath, filename)
data = [
x
for x in split(article_file_path.replace(self.root_path, '').replace(filename, ''))
if x
]
category = data[0]
keywords = data[1:]
article = None
with open(article_file_path, encoding="utf8") as f:
content = f.read()
article = Article(article_file_path, content)
article = Article(article_file_path, content, category, keywords)
if article:
logger.warn('article found in %s: %s', article.category, article)
logger.info('article found in %s: %s', article.category_name, article)
self.articles.append(article)
category = categories.setdefault(article.category, [])
category.append(article.slug)
category = self.categories.setdefault(
article.category_name, Category(article.category_name)
)
category.append(article)
return article
def serialize(self, indent=None):
"""Serialize the current files structure to index.json"""
with open('index.json', 'w') as json_serialized_file:
json_serialized_file.write(to_json(self, indent))
with open(os.path.join(self.output_path, 'index.json'), 'w') as json_serialized_file:
json_serialized_file.write(to_json({"data": self}, indent))
with open("categories.json", "w") as json_serialized_file:
json_serialized_file.write(to_json(self.categories, indent))
with open(os.path.join(self.output_path, "categories.json"), "w") as json_serialized_file:
schema = CategorySchema(many=True)
result = schema.dump(self.categories.values())
json_serialized_file.write(to_json({"data": result}, indent))

15
grnx/schema.py Normal file
View File

@ -0,0 +1,15 @@
"""Serialization module for models objects."""
from marshmallow import Schema, fields
class ArticleCategorySchema(Schema):
title = fields.Str()
slug = fields.Str()
class CategorySchema(Schema):
name = fields.Str()
slug = fields.Str()
articles = fields.Nested(ArticleCategorySchema)

View File

@ -6,7 +6,9 @@ from clize import run
def generate_static_site(input_folder, output_folder):
Site(input_folder)
site = Site(input_folder, output_folder)
site.serialize()
print(site)
if __name__ == "__main__":

View File

@ -5,4 +5,5 @@ pytest==3.7.2
pytest-cov==2.5.1
jinja==2.10
python-slugify==1.2.5
markdown==2.6.11
markdown==2.6.11marshmallow==3.6.1
python-slugify==4.0.0

View File

@ -1,30 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.3.1/css/foundation.min.css">
<meta charset="utf-8">
<title>Cryptocurrency Pricing Application</title>
<title>Grnx</title>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- UIkit CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/uikit@3.5.4/dist/css/uikit.min.css" />
<!-- UIkit JS -->
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.4/dist/js/uikit.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/uikit@3.5.4/dist/js/uikit-icons.min.js"></script>
</head>
<body>
<div class="container" id="app">
<h3 class="text-center">Cryptocurrency Pricing</h3>
<div class="columns medium-4" v-for="(result, index) in results">
<div class="card">
<div class="card-section">
<p> {{ index }} </p>
</div>
<div class="card-divider">
<p>$ {{ result.USD }}</p>
</div>
<div class="card-section">
<p> &#8364 {{ result.EUR }}</p>
</div>
</div>
</div>
</div>
<body>
<div id="app">
<script src="https://unpkg.com/vue"></script>
<script src="vueApp.js"></script>
</body>
</html>
<nav class="uk-navbar-container" uk-navbar>
<div class="uk-navbar-left">Grnx</div>
<div class="uk-navbar-right">
<ul class="uk-navbar-nav">
<li class="uk-active" v-for="(category, article_slugs) in categories.data">
<a href="{{ category.slug }}">{{ category.name }}</a>
</li>
</ul>
</div>
</nav>
<script>
const app = new Vue({
el: '#app',
data() {
return {
categories: [],
}
},
mounted() {
axios
.get('categories.json')
.then(response => (this.categories = response.data));
}
})
</script>
</body>
</html>