forked from github.com/blag
@@ -14,6 +14,7 @@ blag is named after [the blag of the webcomic xkcd][blagxkcd].
|
|||||||
* Theming support using [Jinja2][] templates
|
* Theming support using [Jinja2][] templates
|
||||||
* Generation of Atom feeds for blog content
|
* Generation of Atom feeds for blog content
|
||||||
* Fenced code blocks and syntax highlighting using [Pygments][]
|
* Fenced code blocks and syntax highlighting using [Pygments][]
|
||||||
|
* Integrated devserver
|
||||||
|
|
||||||
blag runs on Linux, Mac and Windows and requires Python >= 3.8
|
blag runs on Linux, Mac and Windows and requires Python >= 3.8
|
||||||
|
|
||||||
|
|||||||
37
blag/blag.py
37
blag/blag.py
@@ -19,6 +19,7 @@ from jinja2 import Environment, ChoiceLoader, FileSystemLoader, PackageLoader
|
|||||||
import feedgenerator
|
import feedgenerator
|
||||||
|
|
||||||
from blag.markdown import markdown_factory, convert_markdown
|
from blag.markdown import markdown_factory, convert_markdown
|
||||||
|
from blag.devserver import serve
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
logging.basicConfig(
|
logging.basicConfig(
|
||||||
@@ -50,7 +51,10 @@ def parse_args(args=None):
|
|||||||
commands = parser.add_subparsers(dest='command')
|
commands = parser.add_subparsers(dest='command')
|
||||||
commands.required = True
|
commands.required = True
|
||||||
|
|
||||||
build_parser = commands.add_parser('build')
|
build_parser = commands.add_parser(
|
||||||
|
'build',
|
||||||
|
help='Build website.',
|
||||||
|
)
|
||||||
build_parser.set_defaults(func=build)
|
build_parser.set_defaults(func=build)
|
||||||
build_parser.add_argument(
|
build_parser.add_argument(
|
||||||
'-i', '--input-dir',
|
'-i', '--input-dir',
|
||||||
@@ -73,9 +77,38 @@ def parse_args(args=None):
|
|||||||
help='Static directory (default: static)',
|
help='Static directory (default: static)',
|
||||||
)
|
)
|
||||||
|
|
||||||
quickstart_parser = commands.add_parser('quickstart')
|
quickstart_parser = commands.add_parser(
|
||||||
|
'quickstart',
|
||||||
|
help="Quickstart blag, creating necessary configuration.",
|
||||||
|
)
|
||||||
quickstart_parser.set_defaults(func=quickstart)
|
quickstart_parser.set_defaults(func=quickstart)
|
||||||
|
|
||||||
|
serve_parser = commands.add_parser(
|
||||||
|
'serve',
|
||||||
|
help="Start development server.",
|
||||||
|
)
|
||||||
|
serve_parser.set_defaults(func=serve)
|
||||||
|
serve_parser.add_argument(
|
||||||
|
'-i', '--input-dir',
|
||||||
|
default='content',
|
||||||
|
help='Input directory (default: content)',
|
||||||
|
)
|
||||||
|
serve_parser.add_argument(
|
||||||
|
'-o', '--output-dir',
|
||||||
|
default='build',
|
||||||
|
help='Ouptut directory (default: build)',
|
||||||
|
)
|
||||||
|
serve_parser.add_argument(
|
||||||
|
'-t', '--template-dir',
|
||||||
|
default='templates',
|
||||||
|
help='Template directory (default: templates)',
|
||||||
|
)
|
||||||
|
serve_parser.add_argument(
|
||||||
|
'-s', '--static-dir',
|
||||||
|
default='static',
|
||||||
|
help='Static directory (default: static)',
|
||||||
|
)
|
||||||
|
|
||||||
return parser.parse_args(args)
|
return parser.parse_args(args)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
60
blag/devserver.py
Normal file
60
blag/devserver.py
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
import multiprocessing
|
||||||
|
from http.server import SimpleHTTPRequestHandler, HTTPServer
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
from blag import blag
|
||||||
|
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def get_last_modified(dirs):
|
||||||
|
"""Get the last modified time.
|
||||||
|
|
||||||
|
This method recursively goes through `dirs` and returns the most
|
||||||
|
recent modification time time found.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
dirs : list[str]
|
||||||
|
list of directories to search
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
int : most recent modification time found in `dirs`
|
||||||
|
|
||||||
|
"""
|
||||||
|
last_mtime = 0
|
||||||
|
|
||||||
|
for dir in dirs:
|
||||||
|
for root, dirs, files in os.walk(dir):
|
||||||
|
for f in files:
|
||||||
|
mtime = os.stat(os.path.join(root, f)).st_mtime
|
||||||
|
if mtime > last_mtime:
|
||||||
|
last_mtime = mtime
|
||||||
|
|
||||||
|
return last_mtime
|
||||||
|
|
||||||
|
|
||||||
|
def autoreload(args):
|
||||||
|
dirs = [args.input_dir, args.template_dir, args.static_dir]
|
||||||
|
logger.info(f'Monitoring {dirs} for changes...')
|
||||||
|
last_mtime = get_last_modified(dirs)
|
||||||
|
while True:
|
||||||
|
mtime = get_last_modified(dirs)
|
||||||
|
if mtime > last_mtime:
|
||||||
|
last_mtime = mtime
|
||||||
|
logger.debug('Change detected, rebuilding...')
|
||||||
|
blag.build(args)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
def serve(args):
|
||||||
|
httpd = HTTPServer(('', 8000), partial(SimpleHTTPRequestHandler,
|
||||||
|
directory=args.output_dir))
|
||||||
|
proc = multiprocessing.Process(target=autoreload, args=(args,))
|
||||||
|
proc.start()
|
||||||
|
httpd.serve_forever()
|
||||||
30
tests/test_devserver.py
Normal file
30
tests/test_devserver.py
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from tempfile import TemporaryDirectory
|
||||||
|
from blag import devserver
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def tempdir():
|
||||||
|
with TemporaryDirectory() as dir:
|
||||||
|
yield dir
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_last_modified(tempdir):
|
||||||
|
# take initial time
|
||||||
|
t1 = devserver.get_last_modified([tempdir])
|
||||||
|
|
||||||
|
# wait a bit, create a file and measure again
|
||||||
|
time.sleep(0.1)
|
||||||
|
with open(f'{tempdir}/test', 'w') as fh:
|
||||||
|
fh.write('boo')
|
||||||
|
t2 = devserver.get_last_modified([tempdir])
|
||||||
|
|
||||||
|
# wait a bit and take time again
|
||||||
|
time.sleep(0.1)
|
||||||
|
t3 = devserver.get_last_modified([tempdir])
|
||||||
|
|
||||||
|
assert t2 > t1
|
||||||
|
assert t2 == t3
|
||||||
Reference in New Issue
Block a user