import datetime import json import os import os.path import re import shutil import uuid from jinja2 import Environment, FileSystemLoader from markdown import markdown from yird.post import NewPostForm, Post from yird.settings import Settings class PostsService: settings = Settings() @classmethod def get_post(cls, post_id): bare_post_path = os.path.join(cls.settings.POSTS_PATH, post_id) with open(bare_post_path + '.json') as f: metadata = json.loads(f.read()) with open(bare_post_path + '.md') as f: content = f.read() return Post( post_id, metadata['title'], metadata['slug'], datetime.date.fromisoformat(metadata['date']), content, metadata['changed'] ) @classmethod def get_posts(cls): posts_path = cls.settings.POSTS_PATH posts = [] paths = os.listdir(posts_path) paths = [p for p in paths if re.search('.*(\\.json)', p)] for path in paths: post_id, extension = os.path.splitext(path) post = cls.get_post(post_id) posts.append(post) return sorted(posts, key=lambda post: post.date, reverse=True) @classmethod def generate_posts(cls): cls.__reset_public_dir() posts = cls.get_posts() template = cls.__get_post_template() for post in posts: cls.__generate_post(template, post) @classmethod def create_post(cls, post_data): id = str(uuid.uuid4()) post = Post( id, post_data['title'], post_data['slug'], datetime.date.fromisoformat(post_data['date']), post_data['content'], ) post.write() return post @classmethod def update_post(cls, post_id, post_data): post = Post( post_id, post_data['title'], post_data['slug'], datetime.date.fromisoformat(post_data['date']), post_data['content'], ) post.write() @classmethod def get_post_form(cls, post=None): if post is None: return NewPostForm(date=datetime.date.today()) return NewPostForm( title=post.title, slug=post.slug, date=post.date, content=post.content ) @classmethod def __generate_post(cls, template, post): settings = cls.settings output_post_dir = os.path.join(settings.PUBLIC_PATH, post.id) metadata_path = os.path.join(settings.POSTS_PATH, post.id + '.json') os.mkdir(output_post_dir) post.content = markdown(post.content) with open(metadata_path) as f: metadata = json.loads(f.read()) metadata['changed'] = False with open(metadata_path, "w") as f: f.write(json.dumps(metadata)) with open(os.path.join(output_post_dir, "index.html"), "w") as f: f.write(template.render(post=post)) @classmethod def __reset_public_dir(cls): shutil.rmtree(cls.settings.PUBLIC_PATH) os.mkdir(cls.settings.PUBLIC_PATH) @classmethod def __get_post_template(cls): loader = FileSystemLoader(cls.settings.TEMPLATES_PATH) env = Environment(loader=loader) return env.get_template('post.html')