5 changed files with 155 additions and 0 deletions
@ -0,0 +1,108 @@
|
||||
import sys |
||||
from functools import reduce |
||||
from pathlib import Path, PurePath |
||||
from queue import Queue, Empty |
||||
from shutil import rmtree |
||||
from typing import Union |
||||
|
||||
# Applying typing definition from aiohttp |
||||
if sys.version_info >= (3, 6): |
||||
PathLike = Union[str, "os.PathLike[str]"] |
||||
else: |
||||
PathLike = Union[str, PurePath] |
||||
# Other custom typings |
||||
Patterns = dict[str, str] |
||||
Pipelines = dict[str, list] |
||||
|
||||
|
||||
class File: |
||||
path: Path # This is the path relative to the website root. It can be an input file, an output file, etc. |
||||
kind: str |
||||
metadata: dict |
||||
raw: str |
||||
|
||||
def __init__(self, path: Path, kind: str, metadata=None, raw: str = ''): |
||||
if metadata is None: |
||||
metadata = {} |
||||
self.path = path |
||||
self.kind = kind |
||||
self.metadata = metadata |
||||
self.raw = raw |
||||
|
||||
|
||||
class Job: |
||||
files: list[File] |
||||
pipeline: list |
||||
|
||||
def __init__(self, files: list[File], pipeline: list): |
||||
self.files = files |
||||
self.pipeline = pipeline |
||||
|
||||
|
||||
class JobQueue(Queue): |
||||
def __iter__(self): |
||||
while True: |
||||
try: |
||||
yield self.get(block=False) |
||||
except Empty: |
||||
break |
||||
|
||||
|
||||
class Website: |
||||
job_queue: JobQueue = JobQueue() |
||||
build_prepared: bool = False |
||||
|
||||
input_path: Path |
||||
output_path: Path |
||||
|
||||
patterns: Patterns |
||||
pipelines: Pipelines |
||||
|
||||
title: str |
||||
author: str |
||||
base_url: str |
||||
|
||||
def __init__( |
||||
self, |
||||
blog_path: PathLike, input_dir: PathLike, output_dir: PathLike, |
||||
patterns: Patterns, pipelines: Pipelines, |
||||
title: str, author: str, base_url: str): |
||||
blog_path = Path(blog_path).expanduser() |
||||
self.input_path = blog_path / input_dir |
||||
self.output_path = blog_path / output_dir |
||||
|
||||
self.patterns = patterns |
||||
self.pipelines = pipelines |
||||
|
||||
self.title = title |
||||
self.author = author |
||||
self.base_url = base_url |
||||
|
||||
def reset(self): |
||||
if self.output_path.exists(): |
||||
rmtree(self.output_path) |
||||
|
||||
def enqueue(self, jobs: list[Job]): |
||||
for job in jobs: |
||||
self.job_queue.put(job) |
||||
|
||||
def execute_pipeline(self, pipeline: list, files: list[File]): |
||||
reduce(lambda f, action: action(self, files), pipeline, files) |
||||
|
||||
def prepare(self): |
||||
if self.build_prepared: |
||||
return |
||||
self.reset() |
||||
for file in self.input_path.rglob('*'): |
||||
if file.suffix in self.patterns: |
||||
kind = self.patterns[file.suffix] |
||||
pipeline = self.pipelines[kind] |
||||
|
||||
self.enqueue([Job([File(file.relative_to(self.input_path), kind)], pipeline)]) |
||||
self.build_prepared = True |
||||
|
||||
def build(self): |
||||
self.prepare() |
||||
for job in self.job_queue: |
||||
self.execute_pipeline(job.pipeline, job.files) |
||||
self.job_queue.task_done() |
@ -0,0 +1,13 @@
|
||||
# Pre-defined pipelines |
||||
from shutil import copy as copy_file |
||||
|
||||
from .core import File, Website |
||||
|
||||
|
||||
def copy(web: Website, files: list[File]): |
||||
for file in files: |
||||
origin = web.input_path / file.path |
||||
target = web.output_path / file.path |
||||
if not target.parent.is_dir(): |
||||
target.parent.mkdir(parents=True) |
||||
copy_file(origin, target) |
@ -0,0 +1,29 @@
|
||||
from setuptools import setup, find_packages |
||||
|
||||
|
||||
def file(name: str) -> str: |
||||
with open(name, 'r') as f: |
||||
return f.read() |
||||
|
||||
|
||||
setup( |
||||
name='blep', |
||||
version='0.0.1', |
||||
description='Static site generator.', |
||||
long_description=file('README.md'), |
||||
long_description_content_type='text/markdown', |
||||
url='https://git.aphrodite.dev/Tools/blep', |
||||
license='CNPLv6', |
||||
author='Artemis', |
||||
author_email='git@artemix.org', |
||||
packages=find_packages(), |
||||
install_requires=[ |
||||
], |
||||
classifiers=[ |
||||
'Environment :: Console', |
||||
'Operating System :: OS Independent', |
||||
'Programming Language :: Python :: 3 :: Only', |
||||
'Topic :: Internet', |
||||
'Typing :: Typed', |
||||
] |
||||
) |
Loading…
Reference in new issue