Compare commits
2 Commits
master
...
features/r
Author | SHA1 | Date |
---|---|---|
Fred Pauchet | b92659f98b | |
Fred Pauchet | 0f07b37d2d |
|
@ -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))
|
||||
|
|
|
@ -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)
|
4
main.py
4
main.py
|
@ -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__":
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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> € {{ 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>
|
Loading…
Reference in New Issue